JavaSE修炼手册(03)--继承

📖1.0 什么是继承

继承是面向对象的一个重要特性,它允许一个类(子类)继承另一个类(父类)的属性和方法。

子类可以继承父类的公共成员变量和方法,并且还可以重写父类的方法或者新增自己的成员变量和方法。

继承的主要目的是实现代码的复用和拓展。通过继承,子类可以从父类继承已有的属性和方法,避免了重复编写相同的代码。子类可以在继承的基础上进行功能的扩展,添加自己的特有属性和方法,实现更多的功能。

在 Java 中,使用关键字 extends 来实现类的继承关系,子类继承父类的语法格式如下:

public class 子类名 extends 父类名 {
    // 子类的成员变量和方法
}

通过继承,子类可以访问父类中的公共成员变量和方法,包括继承过来的和父类中定义的。

继承的特点:

  • 子类继承了父类的特征,可以获得父类的属性和方法。
  • 子类可以重写父类的方法,实现自己特有的行为。
  • 子类可以添加自己的成员变量和方法。
  • 子类可以直接访问父类的非私有成员。
  • 子类与父类之间的继承关系是单向的,父类无法继承子类的属性和方法。
  • Java 中不支持多重继承,即 一个类只能继承一个父类。

静态的不会被继承,因为静态的不属于对象!!!

继承主要解决的问题:

共性的抽取,实现代码复用!

📖1.1 父类成员访问

1.1.1子类中访问父类的成员变量

在子类方法中 或者 通过子类对象访问成员时:

  • 如果访问的成员变量子类中有,优先访问自己的成员变量。
  • 如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
  • 如果访问的成员变量与父类中成员变量同名,则优先访问自己的。

成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。 

如果子类自己有父类也有,一定要访问父类里面的,那么就要用到另一个关键字 super

1.1.2子类中访问父类的成员方法

1.成员方法名字不同
class Base{
    public void methodA(){
        System.out.println("Base中的methodA()");
    }
}


class Derived extends Base{
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
    }

    public void methodC(){
        methodB();   //访问子类自己的B()
        methodA();   //访问父类继承的的A()
//        methodD();   //编译失败,在整个继承系统中没有发现方法D()
        
    }
}

总结:成员方法没有同名时,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错。

2. 成员方法名字相同
 

class Base{
    public void methodA(){
        System.out.println("Base中的methodA()");
    }
    public void methodB(){
        System.out.println("Base中的methodB()");
    }
}

class Derived extends Base{
    public void methodA(int a){
        System.out.println("Derived中的methodA(int)方法");
    }
    public void methodB(){
        System.out.println("Derived中的methodB()方法");
    }
    
    public void methodC(){
        methodA();   //没有传参,访问父类中的A()
        methodA(20);   //传递int参数,访问子类中的A(int)
        methodB();   //直接访问,则永远访问到的都是子类中的B(),父类的无法访问到

    }
}

问题:如果子类中存在与父类中相同的成员时,那如何在子类中访问父类相同名称的成员呢?

比如这里我要访问父类的 B() 方法?

📖1.2 super 关键字!!!

:Java 提供了super关键字,该关键字主要作用:在子类方法中访问父类的成员

有些书上会说  他代表父类对象的引用 -->>  这种说法是错的!!!

严格来说:super 就是一个关键字!!! 只是提高代码的可读性!让别人看到这样访问就知道是访问父类的关键字!!!

 

 如图:

  1. this 访问的时候  不仅可以访问父类,也可以访问子类
  2. 当时使用 this 访问父类 和 子类 的成员变量的时候, 子类优先访问
  3. super 只能访问从父类继承过来的成员变量

也可理解为:

  • this -->>  先在子类找,子类没有 去父类找,父类也没有 编译报错!!!
  • super -->>  直接到父类中找!

【注意】

  1. super只能在非静态方法中使用(和 this 一样,只能在非静态 成员方法/变量 中使用)
  2. 在子类方法中,访问父类的成员和方法
  3. super 在当前类当中 使用 那么 当前类 一定是子类! ! !

super.data   访问父类的成员变量

super.func()   访问父类的成员方法

super()     调用父类的构造方法

总结:

1. 什么是继承?  对共性进行抽取

2. 为什么要继承? 达到代码的复用

3. 子类继承了父类的什么?  

 📖1.3 子类构造方法

当子类继承父类之后,一定要先帮助父类 (只能在子类当中调用父类的构造方法) 进行构造,然后再构造子类自己!!!

 【注意】

  1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用父类构造方法;
  2. 如果父类构造方法是带有参数的,此时需要用户为子类显示定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
  3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
  4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现

在调用构造方法时,super 和 this 不能同时存在。因为他俩都只能在第一行!

 📖1.4 super 和 this

【相同点】

  1. 都是Java中的关键字
  2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
  3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

【不同点】

  1. this 是当前对象的引用,当前对象即调用实例方法的对象,super 相当于是子类对象中从父类继承下来部分成员的引用
  2. 非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
  3. 在构造方法中:this(...)用于调用本类构造方法,super(...) 用于调用父类构造方法,两种调用不能同时在构造方法中出现
  4. 构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...) 用户不写则没有

  📖1.5 初始化 & 代码块的实行顺序

  1. 静态代码块先执行,并且只执行一次,在类的加载阶段执行
  2. 当有对象创建时,才会执行实例代码块,实例代码块执行完成后,最后构造方法执行

 

 📖1.6 protected 关键字

在类和对象中,为了实现封装的特性,Java中引入了访问限定符,主要限定:类或者类中成员能否在类外或者其他包中被访问

  📖1.7 继承方式

🌰单继承:

public class A {
    ······
}
public class B extends A{
    ······
}

🌰多层继承

public class A {
    ······
}
public class B extends A{
    ······
}
public class C extends B{
    ······
}

🌰不同类继承同一个类

public class A {
    ······
}
public class B extends A{
    ······
}
public class C extends A{
    ······
}

🌰多继承(不支持,错的!!!

如果需要实现类似这种多继承的关系,后面会讲到 "接口" ,接口就是为了解决多继承问题!

public class A {
    ······
}
public class B {
    ······
}
public class C extends A,B{
    ······
}// Java 不支持多继承

【注意】Java中不支持多继承

一般我们不希望出现超过三层的继承关系 

  • 如果想从语法上进行限制继承,就可以使用 final 关键字
    public final class Test { //密封类
        ······
    }
    //此时这个类 将不能被继承

  📖1.8 final 

  1. final修饰类时,该类变为密封类,此时这个类 将不能被继承
  2. final修饰变量时,变量就会变成常量
  3. final 修饰数组 对象zu
  4. 我们平时使用的String 字符串类,就是用 final 修饰的,不能被继承
  5. final 修饰方法 :表示该方法不能被重写

 📖1.9 继承与组合

  • 继承表示对象之间是 is-a 的关系,比如:狗是动物,猫是动物
  • 组合表示对象之间是 has-a 的关系,比如:汽车。

组合 是 has a 或 a part of (一部分)

组合 其实就是代码的实现方式,看着像而已,无继承那样的语法

class Student{

}
class Teacher{

}
class School{
    public Student[] students;
    public Teacher[] teachers;

    public School() {
        this.students = new Student[10];
        this.teachers = new Teacher[10];
    }
}

组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据引用场景来选择,一般建议:能用组合尽量用组合。 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小林同学7319

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值