本文描述了关于继承的大部分知识,但是并不全,每篇博客之间的知识都有互串,所以需要把几篇文章合起来看,学会融会贯通!
温馨提示:使用PC端观看,效果更佳!
1.继承是什么
(1)在现实生活中,我们都听说过子承父业这个词,这种也叫继承。
(2)某某小孩很顽皮,这肯定是继承了他爸的基因
那么在计算机中,继承是怎么样的呢?
(1)一个类继承了另一个类,这称为继承;前者成为子类,而后者就是父类
(2)继承机制是面向对象程序设计使代码可以复用的最重要的手段,允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生的类,称为派生类。
2.什么时候用到继承
(1)当几个类中有较多重复的代码时;当两个类的属性很相近时。
(2)例如:
这个时候我们可以用到继承
3.如何实现继承
(1)语法
继承使用到关键字:extends
class 类名 extends 类名 {}
(2)示例
class Animal { public String name; public int age; public void eat() { System.out.println("正在吃"); } } class dog extends Animal { public String color; public void doing() { System.out.println("正在旺旺叫"); } } class Cat extends Animal{ public void doing() { System.out.println("正在喵喵喵"); } }
(3)作用
这样就完成了对共性的抽取,实现了代码的复用
4.关于对象的访问
下面做一些测试,观察默认情况下是如果访问的
(1)子类和父类中不存在相同的变量名字
(2)子类和父类中存在相同变量名字
结果:
直接访问,访问到的是子类中的变量
(3)访问成员方法
结果:
同样,如果子类和父类中存在相同的名字,优先访问子类
(4)访问父类私有成员
我们都知道,当被private修饰之和,直接访问权限就被限制在了同一个类中;那如果是继承它的子类呢?
1)直接访问
2)间接访问
(5)总结
1)通过子类对象的引用,去访问子类和父类中不存在相同名字的变量和方法时,优先在子类中寻找,若子类中不存在该变量或者方法时,才会到父类中寻找,若都不存在,则编译报错。
2)通过子类对象的引用,去访问子类和父类中存在相同名字的变量或方法(不构成重载),同样优先访问子类,子类中不存在才去访问父类,都没有则编译报错。
3)那如果子类和父类中存在相同的名字和方法,该如何访问到父类中的呢?下面介绍一个关键字:super
5.使用super关键字访问父类
这个super关键字和this有三个类似的功能,而super出现的意义就是:在子类的方法中访问父类
(1)super访问父类成员变量
这种一定是要求在子类这个类中,而且是在子类中一个方法内
访问:
结果:前面两个为子类,后面一个为父类
(2)访问父类成员方法
三种访问方式:
结果:
(3)super和this的大致访问
(4)super访问父类构造方法
下面先介绍父类构造方法
6.父类构造方法
在构造方法这里,和前面类的构造方法很类似。不写构造方法时,编译器默认提供,写了不带参数没有实现的构造方法也默认没有提供,但是如果写了带参数的构造方法,编译器则不会再提供
(1)不提供构造方法
第一种情况:正常
第二种情况:正常
第三种情况:
(2)主动提供构造方法
第一种情况:只给子类提供
第二种情况:只给父类提供(报错)
原因解释:当父类提供了构造方法之后,子类就不会再提高任何的构造方法;因为父类需要初始化,但是子类中没有构造方法,无法调用父类的构造方法,所以会报错
做法:在子类中也提供构造方法,并在里面使用super关键字调用父类构造方法
第三种情况:子类父类都提供
根据上面的情况,我们可以做出一些总结
(3)关于构造方法的总结
1)父子类,每次构造子类对象前,都会先完成对父类的构造。也就是说,总是会先调用父类的构造方法,再调用子类的构造方法
2)程序员不提供任何构造方法,编译器都会默认提供
3)当父类手动提供了构造方法,而子类却没有,则会报错,因为子类无构造方法则无法调用
4)针对上面第三点的解释:为什么子类和父类都不提供构造方法时,可以调用到父类构造?
即使是默认的构造方法,在子类构造中,也都会默认有一个super()语句,无论写没写。
当父类手动提供了带参构造方法之后,子类中也就不会再提供任何的构造方法;同理,子类中手动提供了带参构造方法,父类中也不会再提供。但是,前者会报错,因为构造子类前,一定会先去构造父类(但是没有super(),无法调用父类构造);而后者,父类不存在带参构造方法,不需要强制初始化。(存在带参构造方法时,在实例化一定要对其赋值,否则就是报错,上面的终究原因)
(4)使用super()调用父类构造方法
1)默认提供(不细说了)
2)手动提供
class Big { public int a; public Big(int a) { this.a = a; } } class Min extends Big { public int b; public Min(int a, int b) { super(a); this.b = b; } } public class Test3 { public static void main(String[] args) { Min min = new Min(10,20); } }
(5)关于super的细节和注意事项
1)super()必须在子类构造方法中的第一行,否则报错
并且,super()只能出现一次,也不能和this()同时出现(他们都必须在第一行)
2)只能存在于非静态的方法中,依赖对象;用来访问非静态成员方法和字段
7.介绍protected
这是一个关键字,一般是用于修饰成员变量和成员方法
根据上表可知,只要在同一个包中,不同类之间是可以互相使用的;它还多了一条性质,就是只要是父子类关系,在不同的类中也可以互相调用。
下面是不同包中的两个类
(1)不能访问的状态
1)public修饰
2)被protected修饰后
意思就是:在不同包中,不能直接访问被protected修饰的成员变量
(2)允许访问状态
想要访问被protected修饰的成员变量,就要按照下面的步骤来进行
1)使用继承关系
2)使用super关键字访问父类
错误原因就是super不能在静态方法中使用
3)正确访问
访问并且赋值:
8.final关键字
final关键字在java中有三个功能。
(1)修饰变量(2)修饰类(3)修饰方法
(1)修饰变量
1)未修饰时:
public static void main(String[] args) { int a = 520; System.out.println(a); a = 250; System.out.println(a); }
未被修饰时,变量的值是可以被改变的;也就是说,没有被final修饰的520就是250
2)加上修饰
语法:
final 类型 变量名字 = 值;
被fianl修饰的变量,可以理解成变成了一个常量,此时是无法被修改的。
(2)final修饰类
作用:被final修饰的类,不能再被继承,称为密封类
1)修饰前:
2)修饰后:
(3)修饰方法
作用:当这个方法被修饰后,表明这个方法不能再被重写
1)未被修饰
2)被修饰后