继承与多态

1.继承

  1. 概述
    面向对象三大特征:封装、继承、多态。
    继承解决的问题:共性抽取。继承的关系.jpg
  2. 继承的格式
    在继承中,子类就是一个父类。extends

  3. 继承中访问成员变量

    • 直接通过子类对象访问成员变量:
      等号左边是谁,就优先用谁,没有则向上找。
    • 间接通过成员方法访问成员变量:
      方法属于谁则优先用谁,没有则向上找。
  4. 区分子类方法中重名的方法:
    • 局部变量 直接用
    • 本类成员变量 this.
    • 父类成员变量 super.
  5. 成员方法访问规则:
    当成员方法同名,创建的对象是谁,就优先用谁,没有则向上找。
  6. 重写注意事项:
    • 保证方法名相同,参数列表也相同
    • 子类返回值必须【小于等于】父类返回值范围
    • 子类方法权限必须【大于等于】父类方法权限修饰符。
  7. 继承中构造方法访问
    • 子类构造方法中默认隐含“super()”
    • 子类构造可通过super关键字来调用父类重载构造
    • super的子类调用必须是子类构造的第一个语句
    • 子类必调用父类构造方法
  8. super 与this关键字图解

super与this关系图解.jpg

  1. java继承的三个特点
    • java语言是单继承的,一个类的直接父类只能有一个。
    • java语言可以多级继承
    • 一个子类的父类是唯一的,但是一个父类可以有多个子类。

2.抽象类

  1. 抽象的概念
    抽象方法:如果父类中某个方法不确定如何进行{}方法体实现,那么他应该是一个抽象方法。
  2. 抽象方法与抽象类的格式public abstract class Animal{} public abstract void eat(); }

    • 不能直接new抽象类
    • 必须使用子类继承抽象父类
    • 子类必须覆写父类所有抽象方法

注意事项:

  1. 1. 一个抽象类不一定会有抽象方法,它也是抽象类。

3. 接口

  1. 接口内方法定义:
    1.7:1. 常量
    2. 抽象方法
    1.8:3. 默认方法```
    1. 静态方法 ```
      1.9: 5. 私有方法
  2. 抽象方法:
    接口中抽象方法前缀修饰符,必为public abstract,可省略
    使用:implements
    接口必须依靠实现类来使用。
  3. 默认方法:public default
    一般用于接口升级
  4. 静态方法:public static void MyInterfaceStatic(){} //注意不能通过接口实现类调用接口的静态方法

  5. 私有方法:
    一般用于抽取重复代码,代码放入接口私有方法,不可被实现类访问:

    1. 普通私有方法:解决多个默认方法之间的重复代码问题
    2. 静态私有方法:解决多个静态方法之间的重复代码问题
  6. 常量的定义与使用```java 注意事项:
  7. 只可以定义public static final修饰,即常量,修饰词可省略。
  8. 常量必须赋值。
  9. 常量名使用完全大写字母,且用下划线分隔 ```

  10. 注意事项:

    1. 接口不可有静态代码块或构造方法。
    2. 一个类可以实现多个父类。
    3. 若多个接口用相同的抽象方法,那么子类只需要覆写一个。
    4. 如果实现类没有实现所有的抽象方法,那么实现类必须是一个抽象类。
    5. 如果多个接口有冲突的默认方法,那么必须被重写
    6. 一个类如果直接父类和接口中的方法冲突,那么优先继承父类方法。
    7. 类是单继承的,直接父类只能有一个。
      类与接口是多实现的,一个类可以实现多个接口。
      接口与接口之间是多继承的。

4. 多态

  1. 多态格式:
    父类引用指向子类对象父类名称 对象名 = new 子类名称(); 接口名称 对象名 = new 实现类名称();

  2. 多态中成员变量
    直接通过对象名称访问成员变量,等号左边是谁,优先用谁,否则向上找。
    间接通过成员方法访问成员变量,看该方法属于谁,优先用谁,没有则向上找。

  3. 成员方法:
    看new的是谁就优先用谁,没有则向上找。
    口诀:编译看左边,运行看右边。
  4. 成员方法与成员变量之间的多态.jpg
  5. 对象的向上转型:创建子类对象当父类使用。父类名称 对象名 = new 子类名称(); Animal animal = new Cat(); 把子类对象当做父类看待来使用。 注意事项:向上转型一定是安全的。

  6. 对象的向下转型:还原子类名称 对象名 = (子类名称) 父类对象; 将父类对象还原成原来的子类对象。 注意:只能向下还原为原来的对象。

  7. 用instanceof关键字进行向下转型:对象名 instanceof 类名称:返回boolean if(animal instanceof Dog){ Dog dog = (Dog)animal; dog.watchHouse(); }

    5.final


    常见四种用法:

    1. 修饰类:
      类不可被继承。
    2. 修饰方法:
      方法不可被覆盖重写。
    3. 修饰局部变量:
      成为常量,不可被更改。修饰引用类型,地址不可被改变。
    4. 修饰成员变量:
      由于成员变量会有默认值,所以必须手动赋值。
      对于final修饰的成员变量,要么直接赋值,要么通过构造函数赋值。

      6.权限修饰符

类的权限修饰符.jpg

7.内部类

  1. 成员内部类
    使用:

    • 在外部类对象中调用外部类方法,再间接使用内部类方法
    • 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
      Body.Heart heart = new Body().new Heart();
      
  2. 内部类同名变量的访问:

访问外部类重名变量.jpg

  1. 局部内部类

类的权限修饰符.jpg
如果希望访问所在方法的局部变量,那么这个局部变量必须是有效final的。

  1. 匿名内部类(重)
    如果接口的实现类只需要使用唯一的一次,那么这种情况下可以省略该类的定义,而改为使用匿名内部类。
    格式:``` 接口名称 对象名 = new 接口名称(){ //覆盖重写所有抽象方法 } //使用匿名内部类 MyInterface obj = new MyInterface(){ @override public void method(){
     System.out.println("匿名内部类实现了方法");
    
    } }; obj.method(); //可以省略类的单独定义

//注意事项: 1.匿名内部类在创建对象时只能使用唯一一次,若要多次使用那么就需要创建单独的实现类。 2.匿名对象是在调用方法时只能调用一次。匿名内部类也可以使用匿名对象。 ``` 匿名内部类+匿名对象.jpg

  1. 类作为成员变量类型:
    没啥特殊的。
  2. 接口可以作为成员变量类型,方法的参数和返回值