复习总结四
总结
继承
继承的定义
继承是在一个已有类的基础上构建新类, 新类除了继承已有类的属性和方法, 还可以根据需要增加新的属性和方法.
- 新类称作子类(或派生类), 已有类称作父类(或超类)
- 可以说子类继承父类, 也可以说父类派生出子类
1 | class <子类名> extends <父类名> { |
父类可以是自己编写的类, 也可以是已有的类或java类库中的类
子类从父类继承的成员变量和成员方法和子类自己声明的一样
- 如果一个类没有声明继承某个父类, 那么这个类默认是Object的子类
class A {...}
与class A extends Object{...}
是等价的- Java中所有的类都直接或间接的继承Object类,
Object
是所有Java类
的根父类
- Java只支持单继承, 不支持多重继承, 一个类只能有一个父类, 但是多个类可以继承同一个父类
-
子类可以继承父类的实例变量和实例方法
-
子类不继承父类的构造方法
-
子类可以继承父类的类变量和类方法.被继承的类变量和类方法, 可以通过子类对象和父类对象访问, 还可以通过子类名或父类名访问
-
子类从父类继承的成员变量和成员方法的访问权限不变
-
子类和父类在同一个包中, 那么子类能够继承父类的非private的成员变量和成员方法
-
子类和父类不在用一个包中, 那么子类只能继承父类的protected和public成员, 不能继承父类友好成员和private成员
子类对象的创建
- 创建并初始化父类的静态成员变量(如果有, 只在加载父类时执行一次)
- 创建并初始化子类的静态成员变量(如果有, 只在加载子类时执行一次)
- 创建并初始化父类的实例成员变量
- 调用父类的构造方法;
- 创建并初始化子类的实例成员变量
- 调用子类的构造方法.
任何子类对象在创建时, 总是从该子类的继承链的最顶端开始依次往下执行: 创建每个父类的成员变量并调用父类的构造方法, 直到创建该子类自己的成员变量并调用自己的构造方法.
成员变量的隐藏和成员方法的重写
- 当子类和父类有同名成员变量时, 在子类方法中访问的是子类的成员变量, 在父类方法中访问的是父类的成员变量
方法重写
- 在子类中定义一个方法, 这个方法的名字、参数、返回值类型与从父类继承的某个方法完全相同, 这就是子类对父类方法的重写(或者叫覆盖)
通过子类对象或在子类内部
调用同名方法时, 调用的总是子类重写的方法- 如果在子类内部想使用被重写的父类方法, 可以使用关键字super
重写父类方法时, 不能降低方法的访问权限
- 子类拥有名字相同而参数不同的两个方法, 这是
方法的重载
静态方法不会被重写
super
super关键字表示当前对象的父类
- 在子类的构造方法中, 使用super关键字指定调用父类的某个构造方法
- 在子类, 通过super关键字访问父类的成员变量和成员方法
super关键字只能用于构造方法和实例方法, 不能用于类方法
使用super关键字调用父类的构造方法
super语句必须是第一条语句
- 在子类的构造方法中, 通过"super(参数列表);"的形式, 指定调用父类的某个构造方法, 由参数列表确定调用父类哪个构造方法
使用super关键字访问父类的成员变量和成员方法
- 如果子类想访问父类被隐藏的成员变量或被重写的成员方法, 可以使用super关键字
- 访问父类的任意成员变量和成员方法, 都可以使用super关键字, 只是在不引起歧义的情况下一般省略super
final类 和 final 方法
- 用final关键字修饰的类称为final类
final类不能被继承, 即不能有子类
- 用final关键字修饰的方法称为final方法
- 如果一个方法被修饰为final方法, 则这个方法可以被继承, 但不能被重写, 即不允许子类重写父类的final方法
上转型与多态
上转型:
1 | class A {...} |
- 子类对象上转型后, 不能再使用子类新增的属性和方法
- 只能使用从父类继承的属性和方法
- 对于父类被子类重写的方法, 实际访问的是子类的方法, 但访问权限还是按照父类方法的访问权限.
- 把子类对象作为实参传给父类的形参, 这也是上转型
- 父类不能被子类继承的属性和方法, 则上转型对象不能访问
- 若存在方法重写, 则访问上转型对象时, 上转型对象原来是哪个类的对象, 则访问的就是哪个类重写的方法
如果两种类型之间没有继承关系, 那么Java编译器不允许在两者间进行类型转换
下转型:
1 | // 上转型 |
- 下转型需要强制转换
- 把一个父类对象强制转换为子类对象, 这是不允许的, 尽管编译能通过, 但不能运行
- 先将子类对象上转型, 然后再下转型, 这是允许的, 上转型对象通过下转型又转换回原来的子类对象, 可以使用子类的全部属性和方法.
- 把子类对象赋值给父类变量叫上转型, 上转型不用强制转换;
- 把父类对象赋值给子类变量叫下转型, 要强制转换.
- 当出现下转型时, 一定要在此之前先执行过上转型, 然后再执行下转型
多态
Java的多态有两种实现方式: 静态多态
, 也就是方法重载
;动态多态
: 和继承及重写
有关.
多态的实现条件: 继承-重写-上转型
抽象类和抽象方法
用关键字abstract修饰的类称为抽象类(abstract类)
1 | abstract class A{...} |
- 抽象类不能用来创建实例, 但是可以被继承, 也可以用来声明变量
不允许使用final和abstract同时修饰一个类和方法
.- 用关键字abstract修饰的成员方法称为抽象方法(abstract方法), 抽象方法只有声明没有实现, 也就是没有方法体
- 抽象方法必须是实例方法, 可以被子类重写(在子类中实现方法体), 重写的方法不再是抽象方法
- 如果子类不重写父类的抽象方法, 则继承该抽象方法
- 有abstract方法的类一定是abstract类, 而abstract类不一定有abstract方法
- 子类如果不重写abstract父类的abstract方法, 则会继承该abstract方法, 从而子类也成abstract类
内部类(不考)
所谓的内部类, 就是定义在一个类内部的类, 包括常规内部类、匿名内部类、静态内部类(不要求掌握)
、局部内部类(不要求掌握)
.
常规内部类
定义在类体中(不是方法体中)且没有用static修饰的类.
定义常规内部类时可以使用private、protected、public、友好等访问权限, 与用于成员变量和成员方法时的规则相同, 可以将常规内部类看作是外部类的一个成员.
- 在常规内部类中可以访问外部类的成员,
- 用"外部类名.this.外部类成员"的形式访问外部类的实例成员,
- 用"外部类名.外部类成员"的形式访问外部类的静态成员.
在外部类的实例方法和构造方法中可以直接声明内部类的变量、创建内部类的对象:
内部类名 变量名 = new 内部类名(…)
在外部类的实例方法和构造方法之外的地方创建常规内部类的对象:
声明内部类的变量: 外部类名.内部类名 变量名
创建内部类的对象: 外部类对象.new 内部类名(…)
也就是要先创建外部类对象, 然后通过外部类对象创建内部类对象