1.引出继承
比如我们要写两个程序
一个大学生考试和一个小学生考试
里面的方法和属性都一样,只不过方法内部的调用有一些差异
public void testing(){
System.out.println(name+"正在考小学数学");//小学里面的
}
public void testing(){
System.out.println(name+"正在考大学数学");//大学生类里面
}
一般都是赋值一份代码,然后进行简单修改
但是这种的代码复用性非常差
解决方法
继承
来提高代码复用性
2.继承的原理图
public class A
public class B extends A
public class C extends A
public class D extends B
public class E extends C
3.实讲
继承的本质是一批类的抽象
代码上展现就是extends
一个包里面我创建三个类
分别是Student Teacher和Person
比如Person是Student和Teacher的父类
public class Student extends Person{
}
这样写说明Student是Person的子类(扩展类)
Student和Teache会继承Person类
无论是方法还是属性(细节1细讲)
4.Object类
Object类是所有类的父类,尽管你不写他也是默认的,所以才有你尽管不引用其他类
也能调用一些方法,这些方法计算Object类中的
5.super和this
防止父类和子类有同名方法或者属性
调用导致的分歧问题
super.work();调用父类的work方法
this.work();调用子类的work方法
如果只写work();
默认的是调用子类的方法,当然属性同理(就近原则)
this用法(详细可以看我的Java之this关键字)
java采用局部优先的思想。局部变量可以和成员变量相同,使用标识符调用时,优先使用局部变量。在实例方法中出现变量名相同时,可以使用this关键字来调用,操作属性(成员变量)。
构造的区别
this调用本类构造(this(参数)//根据参数来确定调用哪个构造器),必须放在构造器的首行。super调用父类构造,必须放在子类构造器首行。
其他区别:
this表示当前对象。super不能表示当前对象
A、this. 变量和super.变量
this.变量 调用的当前对象的变量;
super.变量 直接调用的是父类中的变量。
B、this(参数)和super(参数)方法
this(参数) 调用的是当前类中的构造器;
super(参数) 用于确认要使用父类中的哪一个构造器。
注意
1)在对拥有父类的子类进行初始化时,父类的构造方法也会执行,且优先于子类的构造函数执行;因为每一个子类的构造函数中的第一行都有一条默认的隐式语句super();
2)this() 和super()都只能写在构造函数的第一行;
3)this() 和super() 不能存在于同一个构造函数中。第一,this()和super()都必须写在构造函数的第一行;第二,this()语句调用的是当前类的另一个构造函数而这个另一个构造函数中必然有一个父类的构造器,再使用super()又调用一次父类的构造器, 就相当于调用了两次父类的构造器,编译器不会通过;
4)this和super不能用于static修饰的变量,方法,代码块;因为this和super都是指的是对象(实例)。
6.继承的细节
1.子类的确继承父类的方法和属性,但是有些私有的方法和属性,子类不能直接用需要,父类提供的公共方法来访问
get方法/set方法(封装)操作属性
定义另一个方法里面运行,private方法,访问私有的方法
注意下默认也是,不过如果在同一个包里,默认和public和protected相同
在同包和不同包的定义比较麻烦所以,一般不写默认
但是如果你的父类和子类有同名的情况(都有name)
但是你只给你的父类赋值了,而且子类没有赋值,默认是用子类的name
pupil的testing方法
这个是pupil有name(没赋值)而且Student有name(小袁)的情况
这个是pupil没name,Student有name
当然你也可以
把这个name改为super.name;是一样的效果
也可以用Student.name;
可能父类的父类调用就用
类名.变量名字
2.子类必须调用父类的构造器完成父类的初始化
子类的默认构造器
public 子类名字{
super();//调用的是父类的无参构造器,默认的
}//子类的默认构造器
父类的构造器
如果有无参构造器
子类会默认调用父类的无参构造器
但当子类没有无参构造器,只有有参构造器时
子类的构造器就不能是默认的了,因为你要往父类的构造器传参数的
(一般还是留一个无参构造吧)
//父类构造器
public Student(String name) {
this.name = name;
}
子类没有创建对应的构造器,会报错
解决方法
在自己的构造器里给父类构造器加上参数
3.子类调用父类构造器的细节
当你在本类构造器调用this()
会默认占用super()的位置
super就无了,但是不管怎么样,最后肯定会调用到父类构造器
因为构造器里调用的这个构造器里可能有super()
所以肯定是会有父类的属性的空间的的,这个你放心
就算也调用了this(参数),往下延伸,最后肯定会调用到
当然你可能想三个搞个循环,编译器会直接报错
4.
5.
9思考题
B继承C
然后A继承B
相当于A继承了B和C的所有属性和方法
相当于A继承了B和C