文章目录
- 前言:
- 1、继承的概念
- 2、继承的格式:
- 3、继承的特点:
- 4、什么时候使用继承:
- 5、子类可以继承父类哪些内容
- 6、继承后如何访问成员变量
- 6.1、成员变量不重名
- 6.2、成员变量重名
- 7、继承后如何访问成员方法
- 7.1、成员方法不重名
- 7.2、成员方法重名
- 8、继承中的方法重写
- 9、继承后的构造方法
- 10、super 和 this 关键字的对比
前言:
还在学习的过程中
水平有限,不足之处望请斧正。
1、继承的概念
- 继承是面向对象的三大特征之一
- 继承可以让类和类之间产生父子关系
- 继承可以把多个子类中重复的代码抽取到父类中,子类可以直接使用,减少代码的冗余,提高代码复用性
2、继承的格式:
Java 使用extends 关键字来表示继承关系
public static 子类 extends 父类{}
3、继承的特点:
- 子类可以得到父类的属性和行为 (不是所有的)
- 子类可以在父类的基础上增加新的功能
- Java只能是单继承:一个子类只能继承一个父类
- Java不支持多继承,但是支持多层继承 ( A 可以继承自 B,B可以继承自C )
- Java 中所有的类都直接或者间接继承于 Object 类
- 子类只能访问父类中非私有的成员
4、什么时候使用继承:
当类和类之间存在共性(相同内容) ,并满足 子类是父类中的一种,就可以考虑使用继承
5、子类可以继承父类哪些内容
父类中包括构造方法,成员变量,成员方法
- 构造方法:
不论是非私有的还是私有的都无法继承
- 成员变量:
非私有的可以继承,并且可以使用
私有的可以继承但不能使用
- 成员方法:
非私有的可以继承,私有的不能继承
关于成员变量的补充:在 java 中为了避免子类调用父类方法时逐层寻找,在最顶级父类中建立了一个虚方法表,用来存储经常可能被用到的方法,并且子类可以得到父类的虚方法表,还可以添加自己的虚方法。( 虚方法表只能用于存储 非private方法,非static 方法,非final方法 )
6、继承后如何访问成员变量
6.1、成员变量不重名
如果子类和中父类中的成员变量不重名,则访问时没有影响
public class Test {
public static void main(String[] args) {
Zi zi = new Zi() ;
zi.show();
}
}
class Fu {
int numFu = 10 ;
}
class Zi extends Fu {
int numZi = 5 ;
public void show(){
System.out.println("父类中的num为: " + numFu);
System.out.println("子类中的num为: " + numZi);
}
}
运行结果:
父类中的num为: 10
子类中的num为: 5
6.2、成员变量重名
当成员变量重名时,对成员变量的访问遵循就近原则
- 子类成员变量和父类成员变量重名,在子类中会优先调用子类成员变量
- 如果此时想要访问父类的成员变量可以通过 super 关键字
- 成员变量和局部变量重名时,会优先调用局部变量
- 此时想要访问成员变量可以 使用 this 关键字
- super代表的是父类对象的引用,this代表的是当前对象的引用。
public class Test {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show();
}
}
class Fu {
int num = 10;
}
class Zi extends Fu {
int num = 5;
public void show() {
int num = 1;
System.out.println("num的值为 " + num);
System.out.println("this.num 的值为: " + this.num);
System.out.println("super.num 的值为: " + super.num);
}
}
运行结果:
num的值为 1
this.num 的值为: 5
super.num 的值为: 10
总结:
继承中成员变量的访问特点:就近原则
默认先在局部位置查找,在本类位置查找,最后在父类位置查找
7、继承后如何访问成员方法
7.1、成员方法不重名
如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。
public class Test {
public static void main(String[] args) {
Zi zi = new Zi();
zi.ziMethod();
zi.fuMethod();
}
}
class Fu {
public void fuMethod() {
System.out.println("父类中的fuMethod 方法");
}
}
class Zi extends Fu {
public void ziMethod() {
System.out.println("子类中的ziMethod 方法");
}
}
运行结果:
子类中的ziMethon 方法
父类中的fuMethon 方法
7.2、成员方法重名
如果成员方法重名,则创建子类对象调用该方法的时候,子类对象会优先调用自己的方法。
public class Test {
public static void main(String[] args) {
Zi zi = new Zi();
zi.method();
}
}
class Fu {
public void method() {
System.out.println("父类中的method 方法");
}
}
class Zi extends Fu {
public void method() {
System.out.println("子类中的method 方法");
}
}
运行结果:
子类中的 method 方法
8、继承中的方法重写
在子类中创建一个与父类中相同名称、相同返回值类型、相同参数列表的方法,只是方法体中的实现不同,以实现不同于父类的功能,这种方式被称为方法重写(override),又称为方法覆盖。当父类中的方法无法满足子类需求或子类具有特有功能的时候,需要方法重写。
重写的要求:
- 父类的成员方法只能被它的子类重写。
- 重写方法的名称、形参列表必须与父类中的一致。
- 子类重写父类方法时,访问权限子类必须大于等于父类 ( 空着 < protected < public )
- 子类重写父类方法时,返回值类型子类必须小于等于父类
- 私有方法不能被重写。
- 子类不能重写父类的静态方法,如果重写会报错的。 ( 只有被添加到虚方法表中的方法才能被重写 )
- 重写的方法可以使用 @Override 注解来标识。加上注解后如果有红色波浪线,表示语法错误。
public class Test {
public static void main(String[] args) {
Zi zi = new Zi();
zi.method();
zi.method2();
}
}
class Fu {
public void method() {
System.out.println("父类吃饭");
}
public void method2() {
System.out.println("父亲打儿子");
}
}
class Zi extends Fu {
@Override
public void method() {
System.out.println("子类吃冰淇凌");
}
}
运行结果:
子类吃冰淇凌
父亲打儿子
9、继承后的构造方法
- 父类中的构造方法不会被子类继承
- 子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据,子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化。故子类中所有的构造方法默认先访问父类中的无参构造,再执行自己。
- 子类构造方法的第一行语句默认都是: super(),不写也存在,且必须在第一行。如果想调用父类有参构造,必须手动写super进行调用。
public class Test {
public static void main(String[] args) {
Student stu = new Student() ;
System.out.println("----------------");
Student stu2 = new Student("张三");
}
}
class Person1{
private String name ;
private int age ;
public Person1(){
System.out.println("父类的无参构造方法");
}
}
class Student extends Person1{
private String schoolName ;
public Student() {
//super() ; //调用父类的无参构造,默认存在可以省略
System.out.println("子类的无参构造");
}
public Student(String schoolName) {
//super() ; //调用父类的无参构造,默认存在可以省略
this.schoolName = schoolName;
System.out.println("子类的带参构造");
}
}
运行结果:
父类的无参构造方法
子类的无参构造
----------------
父类的无参构造方法
子类的带参构造
10、super 和 this 关键字的对比
- this :表示当前方法调用者的地址
- super :表示父类存储空间
关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
this | this.成员变量 访问本类成员变量 | this.成员方法 访问本类成员方法 | this() 访问本类构方法(一个构造方法调用其它构造方法) |
super | super.成员变量 访问父类成员变量 | super.成员方法 访问父类成员方法 | super() 访问父类构造方法 |
今天的分享就到这里了,期待与你共同进步!
如有不足欢迎留言指正 !