• 面向对象(三):常用知识下


    十一、抽象类

    1、抽象类的特点:
    • 抽象类和抽象方法必须用abstract关键字修饰 
      • 抽象类一般会有一个 public 的方法,作为访问的入口。
      • 抽象方法,一般使用 protected 关键字修饰,用于子类重写。
      • 内部使用的方法,为 private 修饰。
    • 抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类。 
    • 抽象类不能实例化 ,但是抽象类有构造方法,作用在于子类访问父类数据的初始化。 
    • 抽象的子类
      • 如果不想重写抽象方法,该子类是一个抽象类。
      • 重写所有的抽象方法,这个时候子类是一个具体的类。
    • 抽象类的实例化其实是靠具体的子类实现的。是多态的方式。
      • AbstractAnimal a = new Cat();
    2、抽象类的成员特点:
    1)成员变量:既可以是变量,也可以是常量。
    • 构造方法:有。用于子类访问父类数据的初始化。 
    • 成员方法:既可以是抽象的,也可以是非抽象的。 
    2)抽象类的成员方法特性:
    • 抽象方法: 强制要求子类做的事情。 
    • 非抽象方法: 子类继承的事情,提高代码复用性。
    3、abstract不能和哪些关键字共存?
    • private 冲突 。abstract 必被重写,private只能自己实现。 
    • final 冲突 。 
    • static 无意义 。

    十二、接口

    1、接口的特点
    • 接口用关键字interface表示  
    • 类实现接口用implements表示 
    • 接口不能实例化 ,按照多态的方式来实例化。
    • 接口的子类 
      • 可以是抽象类。但是意义不大。 
      • 可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
    2、接口成员特点
    1)成员变量,只能是常量,并且是静态的。
    • 默认修饰符:public static final 
    2)构造方法:接口没有构造方法,但是超类 Object有无参的构造方法。
    3)成员方法:只能是抽象方法。
    • 默认修饰符:public abstract   
    3、继承与实现
    1) 类与类:
    • 继承关系,只能单继承,可以多层继承。 
    2)类与接口:
    • 实现关系,可以单实现,也可以多实现。 
    • 并且还可以在继承一个类的同时实现多个接口。 
    3)接口与接口:
    • 继承关系,可以单继承,也可以多继承。
    3、抽象类和接口的区别:
    1)成员区别
    • 抽象类: 
      • 成员变量:可以变量,也可以常量
      • 构造方法:有
      • 成员方法:可以抽象,也可以非抽象
    • 接口:
      • 成员变量:只可以常量
      • 成员方法:只可以抽象 
    2)关系区别
    • 类与类
      • 继承,单继承
    • 类与接口
      • 实现,单实现,多实现
    • 接口与接口
      • 继承,单继承,多继承
    3)设计理念区别(《java编程思想》)
    • 抽象类 
      • 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
    • 接口 
      • 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。

    十三、形式参数和返回值的问题深入研究

    1、 形式参数:
    • 基本类型:值
    • 引用类型 
      • 类名:需要的是该类的对象 
      • 抽象类:需要的是该抽象的类子类对象 
      • 接口:需要的是该接口的实现类对象
    2、 返回值:与形参一致

    十四、包

    1、packag 关键字
    2、import 关键字

    十五、权限修饰符

    1、public :公开,全部可以访问
    2、protected:所有子类(同包或不同包)、同包下的所有类访问
    3、default:同包下所有类。
    4、private:本类内部访问

    十六、内部类

    1、特点
    • 1)定义在其他类的内部,这个类就被称为内部类。 类A中定义了一个类B,类B就是内部类
    • 2)内部类可以直接访问外部类的成员,包括私有。 
    • 3)外部类要访问内部类的成员,必须创建对象。(且访问不同的内部类,方式不同)
    2、分类:
    • 成员内部类:在成员位置定义的类
    • 局部内部类:在局部位置定义的类
    3、 访问:
    • 内部类可以直接访问外部类的成员与方法。
    • 访问成员内部类的成员。 
    1. <span style="font-family:Arial;font-size:18px;">外部类名.内部类名 对象名 = 外部类对象.内部类对象;
    2. Outer.Inner oi = new Outer().new Inner();</span>
    • 在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
    1. <span style="font-family:Arial;font-size:18px;"> //只能在局部位置访问局部内部类
    2. InnerObject2 tInnerObject2 = new InnerObject2();
    3. tInnerObject2.C();</span>

    • 静态方法不能创建内部类实例对象 (多线程的时候,在main方法中需要起线程,会出现这个问题)
      • 原因: 内部类可以访问外部类的成员变量,成员变量是在对象创建后才分配空间的,静态方法中可以不创建对象即访问对象的方法。
      • 如 Outputer是内部类,可以访问外部类的成员变量,即一定有了外部类的实例对象,但是在main方法中根本不需要创建外部类对象,就矛盾了。 
    4、 成员内部类的修饰符:
    • private 为了保证数据的安全性 。
    • static 为了方便访问数据 。
      • 注意:静态内部类访问的外部类数据必须用静态修饰。
      • 内部类用静态修饰是因为内部类可以看出是外部类的成员
      • 成员内部类被静态修饰后的访问方式是
        • 外部类名.内部类名 对象名 = new 外部类名.内部类名();
        • 外部类名.内部类名.方法名()
      • static 不能修饰外部类,但是可以修饰内部类。
    5、成员内部类面试题
    • 内部类和外部类没有继承关系。 
    • 变量的就近原则。
    • this 的限定当前对象的功能。
    • 通过外部类名限定this对象 :Outer.this
    6、 局部内部类
    1)面试题: 局部内部类访问的局部变量必须用 final 修饰 。(动态代理会有涉及)
    • 局部变量是随着方法的调用而在栈中调用,随着调用完毕而消失。而new出来的局部内部类,在堆内存的内容并不会立即消失。
    • 这时就出现一个现象,局部内部类需要访问局部变量,而局部变量已经消失。
    • 所以,我们给局部变量加 final 修饰,加入final修饰后,这个变量就成了常量。(可以使用javac查看class文件)
    • 既然是常量,你消失了,我在内存中存储的是数据的值,所以,我还是有数据在使用。
    7、匿名内部类
    1) 匿名内部类 :就是内部类的简化写法。
    2)前提:存在一个类或者接口 。这里的类可以是具体类也可以是抽象类。
    3)格式: 
    1. <span style="font-family:Arial;font-size:18px;"> new 类名或者接口名(){
    2. 重写方法;
    3. }</span>

    4)本质是什么呢? 是一个继承了该类或者实现了该接口的子类匿名对象。

    8、匿名内部类的使用

    1. <span style="font-family:Arial;font-size:18px;"> //匿名内部类在开发中的使用
    2. //匿名内部类的本质是继承类或者实现了接口的子类匿名对象
    3. pd.method(new Person(){
    4. public void study() {
    5. System.out.println("好好学习,天天向上");
    6. }
    7. });</span>


    9、匿名内部类的面试

    1. <span style="font-family:Arial;font-size:18px;">匿名内部类面试题:
    2. 按照要求,补齐代码
    3. interface Inter { void show(); }
    4. class Outer { //补齐代码 }
    5. class OuterDemo {
    6. public static void main(String[] args) {
    7. Outer.method().show();
    8. }
    9. }
    10. 要求在控制台输出”HelloWorld”</span>

    1)Outer.method()可以看出method()应该是Outer中的一个静态方法。
    2)Outer.method().show()可以看出method()方法的返回值是一个对象。
        又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。
    1. <span style="font-family:Arial;font-size:18px;">class Outer {
    2. //补齐代码
    3. public static Inter method() {
    4. //子类对象 -- 子类匿名对象
    5. return new Inter() {
    6. public void show() {
    7. System.out.println("HelloWorld");
    8. }
    9. };
    10. }
    11. }</span>

     

    十七、面向对象的特征

    (一)封装
    1、利用 private 属性修饰成员变量。使得在类体外无法通过对象直接访问成员变量。
    2、创建成员变量的setXxx() 和 getXxx() 方法,访问set| get方法来访问成员变量。
    (二)继承
    1、Java的单继承,利用接口实现多继承。
    2、子类可以重写父类的方法,也可以不重写。
    3、super关键字,用于子类的构造函数中,调用父类的构造函数。
    (三)多态
    1、前提
    • 有继承
    • 有重写方法
    • 父类引用指向子类对象
    2、对象转型:
    • 向上转型:F f = new Z();
    • 向下转型:Z z = (Z)f;
    3、以后开发,使用接口处理。如
    • XXXDao 和 XXXDaoImpl。
    • 如注入的时候,可以使用接口处理。
    4、多态的实现方式
    • 具体类多态(几乎没有)
    • 抽象类多态(常用)
    • 接口多态(最常用)

  • 相关阅读:
    【刷题】只出现一次的数字(三种解法)
    【Node.JS 】服务器相关的概念
    TortoiseGit设置作者信息和用户名、密码存储
    从零复现PyTorch版(3)
    软考 系统架构设计师之回归及知识点回顾(3)
    (附源码)springboot电影选座订票app 毕业设计 011439
    HTML学习-----HTML开发代码构成
    【ATT&CK】MITRE Caldera 朴素贝叶斯规划器
    Bluespec SytemVerilog 握手协议接口转换
    Linux安装Tomcat最新版
  • 原文地址:https://blog.csdn.net/u012228718/article/details/44926425