Java基础学习day06
简介:
本节学习Java继承与多态核心概念:继承通过extends实现,子类可复用父类非私有成员,支持单继承与多层继承,遵循就近原则并可用super调用父类成员;方法重写需满足权限与返回值约束,常用于重写toString等。多态基于继承,实现父类引用指向子类对象,提升扩展性但无法直接访问子类独有方法,可通过instanceof安全类型转换。
Java基础学习day06
继承
1.认识继承
a.什么是继承
- Java中提供了一个关键字extends,用这个关键字,可以让一个类和另一个类建立起父子关系。
public class Student extends People
public class Teacher extends People
b.子类能继承什么
- 子类能继承父类的非私有成员(成员变量、成员方法)。
c.继承后对象的创建
2.权限修饰符
a.定义
- 就是是用来限制类中的成员(成员变量、成员方法、构造器)能够被访问的范围。
-
3.继承的特点
a.单继承
b.多层继承
c.祖宗类
- Java中所有类,要么直接继承了Object , 要么默认继承了Object , 要么间接继承了Object。
d.就近原则
- 在子类方法中访问其他成员(成员变量、成员方法),是依照就近原则的。 先子类局部范围找,然后子类成员范围找,然后父类成员范围找,如果父类范围还没有找到则报错。
- 如果子父类中,出现了重名的成员,会优先使用子类的,如果此时一定要在子类中使用父类的,可以通过super关键字,指定访问父类的成员。
4.方法重写
a.定义
- 当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写。
- 重写小技巧:使用Override注解,他可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性也会更好。
b.注意事项
- 子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限( public > protected > 缺省 )。
- 重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
- 私有方法、静态方法不能被重写,如果重写会报错的。
c.常见场景
- 子类重写Object类的toString()方法,以便返回对象的内容。
5.子类构造器的特点
a.特点
- 子类的全部构造器,都会先调用父类的构造器,再执行自己。
b.子类构造器是如何实现调用父类构造器的
- 默认情况下,子类全部构造器的第一行代码都是 super() (写不写都有) ,它会调用父类的无参数构造器。
- 如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(….),指定去调用父类的有参数构造器。
c.super(…)调用父类有参数构造器的常见应用场景
d.this(…)调用兄弟构造器
- 任意类的构造器中,是可以通过this(…) 去调用该类的其他构造器的。
e.this(...)和super(…)使用时的注意事项
- this(…) 、super(…) 都只能放在构造器的第一行,因此,有了this(…)就不能写super(…)了,反之亦然。
多态
1.认识多态
a.定义
- 多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态。
People p1 = new Teacher();
People p2 = new Student();
b.多态的前提
- 有继承/实现关系;存在父类引用子类对象;存在方法重写。
c.注意事项
- 多态是对象、行为的多态,Java中的属性(成员变量)不谈多态。
2.多态的好处
a.使用多态的好处
- 在多态形式下,右边对象是解耦合的,更便于扩展和维护。
- 定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强、更便利。
b.多态的问题
3.多态下的类型转换
a.自动类型转换
People p = new Teacher();
b.强制类型转换
c.强制类型转换注意事项
- 存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错。
- 运行时,如果发现对象的真实类型与强转后的类型不同,就会报类型转换异常(ClassCastException)的错误出来。
People p = new Teacher();
Student s = (Student) p;
d.小方法
- 使用instanceof关键字,判断当前对象的真实类型,再进行强转。
- 对象 instanceof 类型 。
public static void go(People p) {
p.run();
if (p instanceof Teacher) {
Teacher t = (Teacher) p;
t.say();
} else if (p instanceof Student) {
Student s = (Student) p;
s.eat();
}
}