【JAVA SE】继承

✨✨欢迎大家来到Celia的博客✨✨

🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉

所属专栏:JAVA

个人主页Celia's blog~

目录

 引言

一、继承

1.1 继承的概念

 1.2 继承语法

 1.3 父类成员的访问

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

1.3.1.1 子类父类中的成员变量不同名

1.3.1.2 子类父类中的成员变量同名

结论:

1.3.2 在子类中访问父类的成员方法

1.3.2.1 子类父类中的成员方法不同名

1.3.2.2 子类父类中的成员方法同名

结论: 

1.4 super关键字

1.4.1 子类构造方法

1.5 关于super和this

1.6 关于继承方式


 

 引言

  在Java中,我们可以定义一个类来描述一个对象,但在某些情况下,被描述的对象的属性比较特殊,甚至某些对象之间还会有一定的关联,这个时候就需要通过继承来实现这些复杂的关系。

比如:猫猫、狗狗,它们都属于动物的范畴。

一、继承

有如下代码:

class Dog{
    public String name;
    public int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(this.name + " " + "正在吃狗粮");
    }
}
class Cat{
    public String name;
    public int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(this.name + " " + "正在吃猫粮");
    }
}

我们发现,这两个类的定义有共同之处:都具有名字、年龄

那我们能不能简化一下代码,把名字、年龄单独抽取出来呢?

1.1 继承的概念

  继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类(子类)。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用

 1.2 继承语法

class 子类名 extends 父类名{
     //...
}

extends 是Java中继承的关键字,用来实现继承。我们可以额外定义一个Animal类,让Dog和Cat类继承它,代码如下:

class Animal{
    public String name;
    public int age;
}
class Dog extends Animal{  //继承


    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(this.name + " " + "正在吃狗粮");
    }
}
class Cat extends Animal{


    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println(this.name + " " + "正在吃猫粮");
    }
}
  • 我们把继承的类叫做子类/派生类,被继承的类叫做父类/基类/超类
  • 父类的成员方法和成员变量会一并继承到子类当中。
  • 子类可以当作包含了父类的成员变量,并且可以使用父类的成员方法。

 1.3 父类成员的访问

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

1.3.1.1 子类父类中的成员变量不同名
class A{
    int a;
    int b;
}

public class Text extends A{
    int c;
    public void func(){
        a = 10;//访问父类的成员变量
        b = 20;//访问父类的成员变量
        c = 30;//访问自己的的成员变量
    }
}
1.3.1.2 子类父类中的成员变量同名
class A{
    int a;
    int b;
}

public class Text extends A{
    int b;
    public void func(){
        a = 10;//访问父类的成员变量
        b = 20;//访问自己的成员变量
    }
}
结论:

 在  子类方法中/通过子类对象  访问父类的成员变量时:

  •  如果子类有,优先访问子类自己的成员变量。

  • 如果子类没有,父类有,则访问父类的成员变量。

  • 如果子类父类都没有,则报错。

1.3.2 在子类中访问父类的成员方法

1.3.2.1 子类父类中的成员方法不同名
class A{
    public void f(){
        System.out.println("xxx");
    }
}

public class Text extends A{

    public void func(){
        System.out.println("aaa");
    }

    public void func2(){
        func();//访问子类自己的
        f();//访问父类的
    }
}
1.3.2.2 子类父类中的成员方法同名
class A{
    public void f(){
        System.out.println("xxx");
    }
}

public class Text extends A{

    @Override
    public void f(){
        System.out.println("aaa");
    }

    public void func2(){
        f();//访问子类自己的,构成方法重写
    }
}

方法重写是指子类在继承父类的同时,重新定义父类中已经存在的方法。子类可以根据自己的需要来改变方法的实现,但方法的名称参数列表返回类型必须与父类中被重写的方法一致。此时调用的是父类的方法,但是实际执行的是子类中重写的方法。这种在运行时才确定调用哪个方法的情况叫做动态绑定

结论: 
  • 通过子类对象访问父类与子类中不同名的成员方法时,优先在子类中找,如果子类没有,再去父类中找,找到则访问,未找到则报错。
  • 如果子类对象访问父类和子类中同名方法时,如果参数列表不同,构成重载,会根据传入参数列表的不同在编译时确定调用哪个方法(静态绑定)。如果参数列表相同,构成重写,则会在运行时调用子类重写的方法(动态绑定)。

1.4 super关键字

  如果子类和父类有同名的成员变量,会优先调用子类的成员变量。如果想要调用父类的成员变量,this引用是做不到的。这时,就需要用到super关键字,来专门访问父类成员。

class Animal{
    public String name = "小黑";
    public int age;
}

class Dog extends Animal{
    public String name = "汪汪";
    public void func(){
        System.out.println(super.name);//在这里会输出“小黑”
    }
}

在以上代码中,如果我们调用func,会输出小黑:

注意事项:super 和 this 一样,都是依赖于对象的,所以只能在非静态方法中使用。 

1.4.1 子类构造方法

  如果一个子类继承了一个父类,那么在子类的构造方法中,必须先调用父类的构造方法。

class Animal{
    public String name;
    public int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

class Dog extends Animal{
    public Dog(String name, int age) {
        //先调用父类的构造方法
        super(name, age);
        //再给子类的其他成员变量进行初始化.....
    }
}


public class Text {
    public static void main(String[] args) {
        Dog dog = new Dog("小黑",10);
        System.out.println(dog.name + dog.age);
    }
}

注意事项:

  • 调用父类的构造方法必须在子类构造方法的第一行。
  • 如果父类没有自定义的构造方法,编译器会自动添加一个空的构造方法。 

1.5 关于super和this

  • super和this都可以在成员方法中访问:成员变量和成员方法
  • super是访问父类的部分成员变量和成员方法
  • this是访问当前对象的(包括继承的)成员变量和成员方法
  • super和this都可以在构造方法中使用,但是由于它们都必须在第一行,故在构造方法中,this和super不能同时出现 
  • 在有继承关系的子类的构造方法中,一定存在super的调用,如果用户不写,编译器会自动添加,但如果用户不写this,则没有
  • 在多继承体系下,super只能访问直系父类,不能访问父类的父类

1.6 关于继承方式

  1. 单继承:A->B
  2. 多层继承:A->B->C
  3. 不同类继承同一个类: A->B   C->B 
  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Celia~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值