JavaSE学习之--继承和多态(一)

简介: JavaSE学习之--继承和多态

💕"越是不思考的人,越不愿倾听别人说话。"💕

作者:Mylvzi

文章主要内容:JavaSE学习之--继承和多态

一.继承(inheritance)

1.为什么要有继承

   我们前面学过类,类是对现实事物的抽象化处理,而通过类实例化的对象则可以用来表示事物。在现实生活中,事物与事物之间有着千丝万缕的联系,最常见的一种就是“父子关系”,儿子会继承父亲的很多特征,而自己又有自己独特的特征;再比如狗和猫都是动物,都具有动物的一些属性,如年龄,性别,毛发颜色等等等等;为了在计算机中表示这种关系,创建了“继承”!

2.继承的概念

 继承(inheritance):就是对事物共性的抽取,从而实现代码复用;

从和实际生活的联系来讲,继承就是将事物的共同属性抽取出来,用一个大类来表示,比如一个父亲有多个孩子,这些孩子都具有某些共性,如年龄,性别,将这些共同属性抽取出来,创建一个新类“Child”;

从代码实现来讲,继承关系的存在实现了代码的复用,子类继承了父类的属性和方法,大大提高效率;

补充:

       其实Java中有很多这种“对共性进行抽取从而达到代码复用”的思路,比如前面学过的类变量,就是所有对象的共同属性的抽取

对象的共性-->静态成员变量

类的共性-->继承extends

3.继承的语法及代码实现

// 父类
class Animal {
    String name;
    int age;
    public void eat() {
        System.out.println(name+"i am eating!!!");
    }
    public void sleep() {
        System.out.println(name+"i am sleeping!!!");
    }
}
// 子类
// 通过关键字extends表示此类继承于父类
class Dog extends Animal {
    public void bark() {
        System.out.println(name+"汪汪叫!!!");
    }
}
class Cat extends Animal {
    public void mew() {
        System.out.println(name+"喵喵叫!!!");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        dog1.name = "初一";
        dog1.age = 3;
        // dog1的成员变量中并没有name和age,但却能引用,则一定继承于父类
        System.out.println(dog1.name);
        System.out.println(dog1.age);
        dog1.eat();
        dog1.sleep();
        dog1.bark();
    }
}

总结:

1. 继承关键字-->extends,格式为:class 子类 extends 父类

2.子类会继承父类的成员和方法,实例化对象之后直接通过对象就能访问

3.子类继承父类的成员和方法之后,还需要有不同于父类的成员或方法(比如Dog类中的bark)

4.在子类中访问父类成员-->super关键字

 1.子类中访问父类成员

11.不存在同名成员变量

class Base {
    int a;
    int b;
    public void method1() {
        System.out.println("hello1");
    }
}
class Derived extends Base {
    int c;// 类特有的
    public void method2() {
        a = 30;// 访问父类继承下来的变量
        b = 20;// 访问父类继承下来的变量
        c = 10;// 访问子类自己的变量
    }

1.2存在同名成员变量

class Base {
    int a;
    int b;
    public void method1() {
        System.out.println("hello1");
    }
}
class Derived extends Base {
    int a;// 和父类同名
    int c;// 子类特有的
    public void method2() {
        a = 30;// 究竟是给父类赋值,还是给子类赋值?
        b = 20;
        c = 10;
    }

1.3在子类中访问成员方法

class Base {
    int a;
    int b;
    public void method1() {
        System.out.println("hello1");
    }
}
class Derived extends Base {
    int c;
    // 和父类的方法构成了重载
    public void method1() {
        System.out.println("hello2");
    }
    // 子类特有的方法
    public void method2() {
        System.out.println("hello2");
    }
}
public class TestDemo1 {
    public static void main(String[] args) {
        Derived p1 = new Derived();
        p1.method1();
        p1.method2();
        // 输出hello1  hello2
        // 证明先执行子类的方法
        // 既不属于子类,又不属于父类,编译失败
//        p1.method3();
    }
}

总结:

       1.父类,子类存在同名的成员变量,成员方法,优先访问子类的,子类中没有再去父类中寻找,寻找不到就编译报错

       2.子类和父类可构成方法的重载,将参数列表设置为不同,在调用时通过传参调用不同的方法!

1.3 那如何在子类中访问父类的成员呢?通过super关键字!

 由于设计不好或者特殊场景需要,需要在子类中访问父类成员,但如果出现重名编译器会优先访问子类中的,并不会访问父类中的成员变量,那该怎么解决呢?Java中提供了关键字super,该关键字的作用是-->在子类方法中访问父类成员变量

class Base {
    int a;
    int b;
    public void method1() {
        System.out.println("hello1");
    }
}
class Derived extends Base {
    int a;
    int b;
    int c;
    public void method1() {
        a = 10;// 等价于this.a
        b = 20;// 等价于this.b
        // 通过super关键字来访问父类成员
        super.a = 30;
        super.b = 40;
    }

super访问方法:

class Derived extends Base {
    int a;
    int b;
    int c;
    public void method1() {
        System.out.println("hello2 这是子类方法");
    }
    public void method2() {
        a = 10;// 等价于this.a
        b = 20;// 等价于this.b
        // 通过super关键字来访问父类成员
        super.a = 30;
        super.b = 40;
        method1();// 输出hello2
        super.method1();// 输出hello1

总结:

1.super关键字的作用就是在子类方法中访问父类成员变量和方法!

2.super只能在子类的非静态方法中使用,因为super主要用来访问并实例化父类中的实例变量,而实例变量必须依赖于对象,静态方法不依赖于对象,所以super不能在子类的静态方法中使用! (super可以访问父类的类变量,但是不建议,更建议通过类名)

3.super只是关键字,提升了代码的可读性,并不代表对父类成员的引用!

1,4子类的构造方法

 构造方法是用来初始化成员变量的一种特殊方法,其在对象的创建过程中就会被调用,而且即使你不写构造方法,编译器会默认添加一个不带参数的构造方法,给你的成员变量赋初始值;在子类中,既有从父类继承过来的成员变量,又有自己独有的成员变量,那在构造方法中赋值的顺序有没有要求呢?答案是有的,先上结论:

 必须先对父类成员变量进行初始化才能对子类成员变量进行初始化!

也就是说在子类的构造方法中会先调用对父类的构造方法,再对子类的成员变量进行初始化。

class Base {
    int a;
    int b;
    // 父类的构造方法
    public Base() {
        System.out.println("父类的构造方法!!!");
    }
}
class Derived extends Base {
    int a;
    int b;
    int c;
    public Derived() {
        // 会默认有一个不带参数的super()
        // 代表父类的初始化
        System.out.println("子类的构造方法!!!");
    }
}

注意事项:

super()就代表调用父类的构造方法!!!

和this();的含义一样!!!

1.super只能放在第一行,放在其他行就报错

2.如果父类的构造方法带参数,则在子类中调用父类的构造方法时也要带参数!(可以快速创建)
// 带参数的父类的构造方法
    public Base(int a, int b) {
        this.a = a;
        this.b = b;
        System.out.println("这是父类构造方法");
    }
    // 子类中的构造方法
    // 必须先对父类成员变量进行初始化
public Derived(int a, int b, int a1, int b1, int c) {
        super(a, b);// 必须放在第一行
                    // 且必须要传参数
        this.a = a1;
        this.b = b1;
        this.c = c;
        System.out.println("这是子类构造方法");
    }

注意:如果父类提供的是一个显式的构造方法,则在子类中必须利用super进行传参!!!

如果父类的构造方法不带参数,在子类的构造方法中可以不写,因为系统会自动提供一个不带参数的super();

3.在子类的构造方法中super和this不能同时出现,且super只能出现一次

   在构造方法那一节我们学过,对于一个类的构造方法,如果要使用this来调用当前类的其他构造方法,则this只能放在第一行,那如果我既想通过super来初始化父类的成员变量,又想通过this调用当前类的其他构造方法该怎么办?答案是没有办法,如果同时拥有会冲突,只能保证他们不能同时存在!

 为什么只能出现一次呢?原因在于继承结构的逻辑链!在继承结构中,子类会先调用父类的构造方法,再执行自身的初始化逻辑,这种执行顺序是线性的,不需要多次进行父类的初始化!

1.5super和this的比较

 我们学过super和this,发现他们有很多相同点,比如都是通过.操作符来访问变量或方法,那他们有哪些异同点呢?下面来总结一下:

相同点:

1.都是Java中的关键字。

2.都只能在非静态方法中访问非静态成员变量或非静态方法

3.在构造方法中调用时,都必须写在第一行,所以super和this不能同时使用;

不同点:

1.this代表当前对象的引用,用于访问当前对象的成员变量及方法;super是用来访问从父类继承的成员或方法。或者说super是引用对象从父类继承部分的引用

2.在构造方法中,super会有默认的对父类的构造方法(先有父后有子),而this并没有默认的构造方法。

3.this(......) 代表当前对象的构造方法,super(.......)代表父类的构造方法,两者不能同时出现

JavaSE学习之--继承和多态(二)+https://developer.aliyun.com/article/1413490



目录
相关文章
|
9月前
|
Java
【JavaSE专栏64】抽象类和接口,不能被实例化的类有什么用?
【JavaSE专栏64】抽象类和接口,不能被实例化的类有什么用?
155 0
|
2月前
javaSE&多态
javaSE&多态
12 1
|
10月前
|
安全 Java
【JAVASE】多态 下
【JAVASE】多态
|
2月前
|
Java
JavaSE学习之--继承和多态(二)
JavaSE学习之--继承和多态(二)
52 0
|
2月前
|
Java 编译器
JavaSE学习之--继承和多态(三)
JavaSE学习之--继承和多态(三)
46 0
|
2月前
|
存储 Java 编译器
JavaSE学习之--抽象类,接口,内部类(三)
JavaSE学习之--抽象类,接口,内部类(三)
31 0
|
2月前
|
存储 Java 机器人
JavaSE学习之--抽象类,接口,内部类(二)
JavaSE学习之--抽象类,接口,内部类(二)
43 0
|
2月前
|
Java
JavaSE学习之--抽象类,接口,内部类(一)
JavaSE学习之--抽象类,接口,内部类(一)
70 0
|
7月前
|
安全 Java 程序员
JavaSE继承和多态
JavaSE继承和多态
|
7月前
|
Java 程序员 编译器
【JavaSE】面向对象之继承
【JavaSE】面向对象之继承