Java基础之面向对象

Posted 荀令君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础之面向对象相关的知识,希望对你有一定的参考价值。

01. 什么是面向对象?
 
    1. 面向对象是一种思想, 更符合我们思考问题的一种习惯
    2. 将复杂的问题简单化
    3. 将我们从执行者的位置变成了指挥者
 
02. 类与对象的关系?
 
    问题:什么是类?
    
            类是一组相关属性和行为的集合, 可以将类看做为一个模子,或者是一张图纸
                类仅仅是对事物的一种描述, 而对象则是具体存在的事物
                
    问题: 关系是什么?
    
            可以根据类去创建对象.
 
 
03. 成员变量和局部变量的区别?
 
    位置不同:
        成员变量: 类中方法外
        局部变量: 方法中或者是方法的声明上(形参)
    作用域不同:
        成员变量: 在整个类当中
        局部变量: 仅在它所在的大括号中有效
    所属不同:
        成员变量:    所属于对象
        局部变量: 所属于方法
    内存位置不同:
        成员变量: 堆内存
        局部变量: 栈内存
    生命周期不同:
        成员变量: 随着对象的创建而存在, 随着对象的消失而消失
        局部变量: 随着方法的调用而存在, 随着方法的弹栈而消失
 
 
04. 阐述面向对象的三大特征?
 ----------------------------封装、继承、多态、 接口的理解-----------------------------------------------------
    1). 封装
    
        概述: 隐藏实现细节, 仅对外暴露公共的访问方式
    
        问题: 封装指的就是private吗?
            
                private私有仅仅是封装的一种体现形式, 不能说封装就是私有
                
                    封装指的是一种思想, 并不能称之为一个技术点:
                    
                            1. 将一段代码抽取到方法中, 这是对代码的一种封装
                            2. 将数据抽取到类中, 这是对数据的一种封装
        
        问题: 封装的好与弊端是什么?
                好处:
                    1.提高了代码的安全性
                    2.提高了代码的复用性
            
                弊端:
                    封装一般来说没有什么弊端, 非要说的话, 就是调用的时候稍微麻烦了一点.
                    再者就是这哥们写的代码太烂了.                
        
        问题: 封装的原则是?
        
                将不需要对外提供的内容都隐藏起来.
    
    2). 继承
    
        概述: 让类与类之间产生关系, 子父类关系, 子类就可以直接使用到父类中非私有的成员.
    
        问题: 继承的好处&弊端
        
            好处:
                1. 提高了代码的复用性
                2. 提高了代码的维护性
                3. 是多态的前提
            
            弊端:
            
                类和耦合性增强了
                
                    开发的将就高内聚, 低耦合
                    
                        内聚: 自己完成事情的能力
                        耦合: 类与类之间的关系太过紧密
            
        问题: Java中的继承特点是?
        
            答: java只支持单继承, 不支持多继承, 但是可以多层继承
                
                问题: 如果想看某个继承体系中共性的功能看谁?
                    
                        最顶层的类, 最顶层类当中的方法, 只要不是私有的, 所有的子类都会具备一份.
                    
                     如果想使用某个继承体系所有的功能就创建谁?
                    
                         最底层的子类对象.
        
        问题: 继承中构造方法的关系?
        
            答: 在继承当中, 子父类是谁先完成初始化呢?
            
                    父类
                    
                    问题: 初始化一个对象, 使用的是哪个方法?
                    
                            构造方法.
                    
                    
                    问题: 子类在初始化的时候, 是如何访问到父类的构造方法呢?
                    
                    
                            子类的每一个构造方法当中, 第一行都默认隐藏了一个super()的语句, 在访问父类的空参构造.
            
                问题: 为什么子类所有的构造方法默认都要访问父类的空参构造?
                
                        结论: 子类在初始化之前一定会先访问到父类的构造方法, 完成父类的初始化!!!
                
                问题: 如果父类没有空参构造怎么办?
                
                        思路: 父类如果没有空参构造, 那么肯定就有带参构造.
                        
                                只需要通过super()手动访问父类的有参构造即可
                                
                                
                                结论: 子类在初始化的时候, 无论通过什么途径, 都必须要访问到父类的构造方法.
                
        问题: 什么是方法的重写?
        
            答: 在子父类当中, 出现了方法声明一模一样的方法, 返回值类型小于等于父类的类型.
            
                    方法声明一模一样的方法 :
                    
                            1. 方法名需要一致
                            2. 参数列表需要一致
                
                问题: 什么时候需要方法重写?
                
                    当子类需要父类的功能, 子类方法的功能主体又有自己特有的实现方式, 这时候就可以对父类的方法进行重写
                        这样既沿袭了父类的功能, 又定义了子类特有的内容
                        
                    大白话理解:
                    
                        子类觉得父类的方法不好, 或者说过于老旧, 就可以对父类的方法进行重写
                
                问题: 重写和重载的区别是?
                
                    重载(Overload)
                            
                            在同一个类中, 方法名相同, 参数列表不同, 与返回值无关
                            
                                    参数列表不同:
                                            1. 类型不同
                                            2. 个数不同
                                            3. 顺序不同(没有意义)
 
                    重写(Override)                
                    
                            子父类当中, 出现了方法声明一模一样的方法, 返回值类型小于等于父类的类型.
                            
                问题: 方法重写有哪些注意事项?
                
                    a: 子类重写父类的方法, 访问权限必须大于等于父类的权限
                    b: 子类不能重写父类中私有的方法.
                    
    
    
    3). 多态
        
            问题: 什么是多态?
            
                    事物存在的多种形态
            
            问题: 多态的2个前提是?
            
                1. 要有继承实现关系
                2. 要有父类引用指向子类对象.
                
                
                3. 要有方法的重写
                
            
            
            问题: 多态中调用成员的特点?
            
                a: 成员变量
                
                    编译看左边(父类), 运行看左边(父类)
                    
                        原因: 因为是父类的引用, 所以只能看到堆内存当中super的一小块区域, 所以只能拿到父类的数据.
                
                b: 成员方法
                
                    编译看左边(父类), 运行看右边(子类)
                    
                        原因:
                        
                            动态绑定机制:
                            
                                在多态创建对象并调用成员方法的时候, 编译时会检查父类中是否有此方法的声明
                                    如果有: 则编译通过, 但是运行的时候执行子类重写后的逻辑
                                    
                                    没有: 编译失败.
                
                c: 静态成员
                
                    编译看左边, 运行看左边
                    
                        思路: 静态修饰的成员跟类相关, 跟对象没有关系
                        
                                Animal a = new Dog();
                                
                                System.out.prinltn(a.num);        // a.num --> 在编译的时候也会翻译成 Animal.num
                                
                                这时候, 类名是谁, 调用的数据就是谁的.
                                
                
            问题: 多态的优缺点是?
            
            
                    优点 :
                    
                        1. 提高了代码的复用性    -> 有继承保证
                        2. 提高了代码的扩展性
                        
                            问题: 扩展性体现在哪儿?
                            
                                    可以将一个方法的形参定义为父类类型, 该方法就可以接受这个父类的任意子类对象了
                                    
                                    
                                    useAnimal(new Dog());
                                    useAnimal(new Cat());
                                    
                                    public static void useAnimal(Animal a){
                                    
                                    }
                                    
                    弊端:
                    
                        不能调用子类特有的属性和行为.
                        
                            问题: 非要调用怎么办?
                            
                                    向下转型.
                                    
                            向下转型的注意事项:
                            
                                1. 向下转型必须发生在子父类的关系当中
                                    Animal a = new Dog();
                                    Cat c = (Cat)a;        // Dog和Cat没有子父类关系.
                                    
                                2. 向下转型必须要事前转上去, 才能转下来
                                
                                    Animal a = new Animal();
                                    Dog d = (Dog)a;        // 没有提前转上去.
                                    
                            
                                正确案例:
                                    Animal a = new Dog();
                                    Dog d = (Dog)a;
                                    
                         关键字instanceof的作用:
                        
                             判断左边的引用, 是否是右边的数据类型
                             
                                 if(a instanceof Dog){
                                 
                                 }
                                 
                                 
                        问题: ClassCastException异常 -> 类型转换异常
                        
                                当引用数据类型的强转出现了错误, 就会抛出此异常.
 
14. 接口
 
    1). 什么是接口?
    
            接口是对外暴露的规则.
    
    2). 如何定义接口?
    
            使用关键字 interface 接口名{}
    
    3). 接口与类的关系?
    
            实现关系, 可以单实现, 也可以多实现, 但是多个接口名之间, 需要用逗号进行分隔.
            
                
            使用关键字: implements
            
            class 实现类 implements 接口名{
            
            }
                
    
    4). 接口是否可以实例化?
    
            不可以实例化, 因为内部含有抽象方法.
    
    5). 接口中的成员特点?
    
            问题: 接口中可以定义哪些内容?
            
                    jdk1.7:
                        常量  : 只能是常量, 因为即使写成了int num = 10; 系统也会默认加入三个关键字
                                public static final
                        
                        抽象方法 : 即使写成了void show(); 系统也会默认加入2个关键字
                                public abstract
                            
                    jdk1.8
                        默认方法
                            格式:
                            
                                public default 返回值类型 方法名(参数列表){
                                
                                }
                                
                            作用:
                            
                                用于解决接口升级的问题
                        
                        静态方法
                        
                            格式:
                            
                                public static 返回值类名 方法名(参数列表){
                                    方法体;
                                }
                                
                            作用: 也是解决接口升级的问题
                            
                            注意:
                                 接口中的静态方法, 不能使用对象名进行调用, 只能通过接口名.调用
                    jdk1.9
                        私有方法
                        
                            格式:
                            
                                private default 返回值类型 方法名(参数列表){
                                
                                }
                                
                            作用:
                            
                                用于解决接口当中, 多个默认静态方法的代码重复问题.
                                
                            注意:
                            
                                如果子接口继承了多个父接口, 多个父接口当中存在重复的默认方法, 子接口必须重写这个重复的默认方法.
 
15. 类与类,类与接口,接口与接口的关系
 
    1). 类与类:    继承关系, 只支持单继承, 不支持多继承, 但是可以多层继承
    2). 类与接口: 实现关系, 可以单实现, 也可以多实现, 并且可以在继承了一个类的同时, 实现多个接口
    3). 接口与接口: 继承关系, 可以单继承, 也可以多继承.
    
16. 抽象类和接口的区别
 
    1). 成员区别
    
            成员变量:
                接口: 只能是常量
                抽象类: 可以是变量, 也可以是常量
                
            成员方法:
                接口: jdk1.7只能定义抽象方法, jdk1.8可以定义默认方法和静态方法, jdk1.9可以定义私有方法
                
                抽象类: 啥方法都能写.
                
                        抽象类当中, 抽象方法不能跟static共存, 也不能和private共存, 也不能跟final共存
                        
                        static :
                                如果允许被static修饰抽象方法, 就代表可以通过类名.调用没有方法体的抽象方法了, 这样做没有意义
                        
                        private :
                                被abstract修饰的抽象方法, 强制要求子类重写, 而被private修饰的方法, 子类不能重写, 所以二者冲突
                        
                        final :
                                被abstract修饰的抽象方法, 强制要求子类重写, 而被final修饰的方法, 子类不能重写, 所以二者冲突
            构造方法:
            
                接口 : 没有构造方法
    
                抽象类: 有构造方法.
    
    2). 关系区别
    
            抽象类: 继承关系
            
            接口: 实现关系
    
    
    3). 设计理念区别    
    
            抽象类被继承体现的是一种is..a的关系, 内部定义的功能都是共性的内容
            
            接口当中定义的都是扩展的规则, 被体现的都是一种like..a的关系.
            
            
            抽象类: 共性
            接口: 特性
                            
------------------------------------------------------------------------------------------------------------------------------------    
 
 
05. 构造方法
    
    1). 构造方法的作用?
    
         用来给对象中的属性进行初始化的.
        
             一般都会通过有参构造创建对象, 并给属性赋值.
    
    2). 构造方法的格式?
    
        A. 方法名要与类名相同, 大小写也要一致
        B. 没有返回值类型连void都没有
        C. 没有具体的返回值
        
            问题 : 构造方法没有返回值, 可以编写return语句吗?
            
                可以, 但是return后面不能跟上具体的值.
    
    3). 构造方法的注意事项?
    
        如果一个类当中, 没有给出任何构造方法, 那么系统将会默认提供一个空参的构造方法, 但是如果手动给出了有参构造
        
            系统将不会再提供默认的空参构造
            
            建议: 今后空参有参都手动给出.
    
    4). 构造方法可以重载吗?
    
    
            构造方法也是方法, 所以可以进行重载.
    
    
06. 给成员变量初始化有几种方式?
 
    答:    
        1. 通过有参构造初始化
        2. 通过setXxx方法初始化
    
    问题: 两种方式有什么区别?
    
        答案: 一般都是通过有参构造进行(初始化), 再通过setXxx方法(修改)属性值
        
                两者往往是配合使用的
    
07. 什么是静态?
 
    答 : 静态指的就是static关键字, static是一个修饰符
    
        被其修饰的成员有什么特点?
 
 
    1). 静态关键字的特点是?
        a: 随着类的加载而加载, 优先于对象存在
        b: 被类的所有对象所共享
        c: 多了一种调用方式, 可以通过类名.进行调用
        
    2). 静态的好处是?
        a: 调用方便
        b: 节约内存
        
    3). 静态关键字的注意事项?
    
        a:  静态当中只能访问静态成员.
        
        问题: 静态中是否有thissuper关键字? 为什么?
        
                没有, this代表当前对象的引用, this只有在创建对象之后,才会存在, super也是一样.
                
                        静态存在的时候, 有可能对象没有被创建出来, 所以说静态当中没有this和super.
        
08. 静态变量和成员变量的区别?
 
    1. 所属不同:
        静态变量  : 类
        成员变量  : 对象
    2. 内存位置不同
        静态变量  : 方法区中, 字节码文件的静态区
        成员变量  : 堆内存
    3. 内存出现时间不同
        静态变量  : 随着类的加载而加载
        成员变量  : 随着对象的创建而存在
    4. 调用不同
        静态变量  : 多了一种调用方式, 可以通过类名.进行调用, 也可以通过对象名进行调用
        成员变量  : 只能对象名进行调用
 
09. 代码块
 
    1). 什么是代码块?
    
            被一对大括号括起来的代码, 就称之为代码块
    
    2). 代码块的分类?
    
            1. 局部代码块
                位置: 方法中的一对大括号
                作用: 限定了变量的声明周期, 可以提早的释放内存
            
            2. 静态代码块
            
                位置: 类中方法外的一对大括号, 需要加入static修饰
                作用: 一般用于加载驱动, 获得数据库连接
                特点: 随着类的加载而执行, 且只执行一次.
            
            -----------------------------------------
                
            3. 构造代码块
            4. 同步代码块
    
 
 
10. this关键字
    
    1). 什么是this关键字?
    
        this代表当前对象的引用, 谁来调用我, 我就代表谁.
    
    
    2). this关键字的应用场景是?
    
            用来区分局部变量和成员变量的重名问题.
    
11. this和super的区别
 
    1). this和super分别代表什么?
    
            this : this代表当前对象的引用, 谁来调用我, 我就代表谁.
            
            super : 代表的是当前对象父类的引用.
    
    2). 调用方面有什么区别?
    
        成员变量:
        
            this : 可以调用本类的成员变量, 也可以调用父类的成员变量
                    前提: 子父类当中没有出现重名的成员变量.
            super : 可以调用父类的成员变量
        
        成员方法:
        
            this : 可以调用本类的成员方法, 也可以调用父类的成员方法
                    前提: 子父类当中没有出现重名的成员方法.
                    
            super : 可以调用父类的成员方法
        
        构造方法:
        
            this() : 调用本类的构造方法
            
            super() : 调用父类的构造方法
            
            
        简单记: this调用的是本类成员, super调用的是父类成员.
        
12. final关键字
 
    1). 什么是final关键字, 其作用是?
    
    
    2). 被其修饰的xx有什么作用?
    
        a:
        b:
        c:
        
    3). final修饰的成员变量, 初始化时机为?
    
 
13. 抽象类
 
    1). 什么是抽象类?
    
            把像的部分和相似的部分抽取到一个父类当中, 抽象类就是一个特殊的父类.
            
                这个特殊的父类和普通的父类,区别就在于, 抽象类当中可以定义抽象方法.
                
    2). 如何定义抽象类和抽象方法?
        
            通过abstract关键字
            
                类: abstract class 类名{}
                
                方法: public abstract 返回值类型 方法名();
    
    3). 抽象类是否可以创建对象?
    
            不可以, 如果允许的话, 就代表可以调用没有方法体的抽象方法, 这样做没有任何意义.
    
    4). 抽象类的子类?
    
            1. 重写所有的抽象方法        -> 推荐
            
            2. 将自己本身也变成抽象类
    
    
    5). 抽象类的成员特点?
    
        1. 成员变量
                
            可以是变量, 也可以是常量
                
        2. 成员方法
            
            可以是普通的方法, 也可以是抽象方法
        
        3. 构造方法
        
            有, 目的是为了给子类进行初始化的
            
            
        总结: 抽象类当中除了可以定义抽象方法之外, 其余的定义跟普通的类没有区别.
        
 
 

以上是关于Java基础之面向对象的主要内容,如果未能解决你的问题,请参考以下文章

Java基础之面向对象

Java基础学习笔记五 Java基础语法之面向对象

java基础之关于面向对象和面向过程的理解

Java基础之OOP

Java基础之面向对象

一脚踩进java之基础篇12——面向对象