【JavaSE】继承与多态(上篇)

2年前 (2022) 程序员胖胖胖虎阿
222 0 0

✨hello,进来的小伙伴们,你们好呐!✨

🍊🍊系列专栏:【JavaSE】🍵

🍤🍤本篇内容:继承部分知识详解(对准知识点阅读喔!)

🧀🧀作者简介:一名大二即将升大三的科班小白,我很平凡,学会努力!

🌯🌯码云存放仓库gitee:https://gitee.com/king-zhou-of-java/java-se.git

目录

一、继承的概念

二、继承的语法

三、访问父类成员

四、super关键字

五、子类构造方法

六、super和this比较

七、代码块执行顺序

八、final 关键字


 一、继承的概念

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

例如:狗和猫都是动物,那么我们就可以将共性的内容进行抽取,然后采用继承的思想来达到共用

二、继承的语法

🍉在Java中如果要表示类之间的继承关系,需要借助extends关键字。

修饰符 class 子类 extends 父类 {
……
}

实例:我们定义一个父类Animal,两个子类Dog和Cat继承父类Animal。

🍱1.首先我们定义了一个父类Animal,其中包含了两个成员变量name和age,两个成员方法eat()和drink()。

class Animal{
    public String name;
    public int age;
    public void eat(){
        System.out.println(name+"正在吃东西");
    }
    public void drink(){
        System.out.println(name+"正在喝水");
    }
}

🍺2.然后我们定义两个子类(Dog和Cat)继承自Animal。

class Dog extends Animal{
    public void barks(){
        System.out.println(name+"汪汪汪~");
    }
}
class Cat extends Animal{
    public void mew(){
        System.out.println(name+"喵喵喵");
    }
}

🌯3.OK接下来定义我们的测试类。

public class Test1 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        System.out.println(dog.name);
        System.out.println(dog.age);
        dog.eat();
        dog.drink();
        dog.barks();
    }
}

🍥🍥解答:

dog类中并没有定义任何成员变量,name和age属性肯定是从父类Animal中继承下来的。

dog访问的eat()和drink()方法也是从Animal中继承下来的。

a57a0448241544a380ddff2cc41b2c2c.png

三、访问父类成员

🍼1.子类中访问父类的成员变量。

🚎1>子类和父类不存在同名成员变量。

public class Base {
  int a;
  int b;
}
public class Derived extends Base{
  int c;
  public void method(){
    a = 10;   // 访问从父类中继承下来的a
    b = 20;   // 访问从父类中继承下来的b
    c = 30;   // 访问子类自己的c
 }
}

🚌2>子类和父类成员变量同名。

public class Base {
  int a;
  int b;
  int c;
}

public class Derived extends Base{
  int a;        // 与父类中成员a同名,且类型相同
  char b;       // 与父类中成员b同名,但类型不同
  public void method(){
    a = 100;     // 访问父类继承的a,还是子类自己新增的a?
    b = 101;     // 访问父类继承的b,还是子类自己新增的b?
    c = 102;     // 子类没有c,访问的肯定是从父类继承下来的c
    // d = 103;   // 编译失败,因为父类和子类都没有定义成员变量b
 }
}

✈️✈️结论:

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

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

🛰️🛰️2.子类中访问父类的成员方法。

规则与子类访问父类的成员变量相同,这里就不在多余介绍!

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

四、super关键字

⛴️⛴️由于设计不好,或者因场景需要,子类和父类中可能会存在相同名称的成员,如果要在子类方法中访问父类同名成员时,该如何操作?直接访问是无法做到的,Java提供了super关键字,该关键字主要作用:在子类方法中访问父类的成员。

⛽⛽super三个用法:

super.data;访问父类普通成员变量;
super.func();访问父类普通成员方法;
super();调用父类的构造方法;

实例:

🚌1.首先我们定义一个父类A。

class A{
    public String name;
    public  int age;
    public void method1(){
        System.out.println("这是A的method1方法");
    }
    public void method2(){
        System.out.println("这是A的method2方法");
    }
}

 🚋2.然后我们定义子类B继承父类A,在这个子类中有自己的成员变量和成员方法,具体如何访问都写在注释里。

class B extends A{
    public String name;// 与父类中成员变量同名且类型相同
    public double age; // 与父类中成员变量同名但类型不同
    public void method1(int a){
        System.out.println("这是B中的method1方法");
    }
    public void method3(){
        name = "张三";// 对于同名的成员变量,直接访问时,访问的都是子类的
        age = 18;
        super.name = "林青霞";// 访问父类的成员变量时,需要借助super关键字
        super.age = 20; // super是获取到子类对象中从基类继承下来的部分

        //父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法
        method1();//访问父类的method1方法
        method1(30);//访问子类的带一个参数的method1方法
    }
}

⛵⛵注意!

🍊1. 只能在非静态方法中使用。
🍎2. 在子类方法中,访问父类的成员变量和方法。

🍓3.对于父类的private成员变量,子类会继承该成员变量,但是不可以访问!

🍔4.java不支持多继承,即一个类只能继承一个父类。

 五、子类构造方法

即子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法。

什么意思呢?下面给大家演示一下:

🍜🍜1.我们首先定义一个父类A1,包含两个成员变量,一个成员方法。

class A1{
    public String name;
    public int age;
    public void eat(){
        System.out.println(name+"正在吃东西");
    }
}

🍛🍛2.然后我们定义一个子类B1继承自父类A1,子类中新增一个成员变量color。

class B1 extends A1{
    public String color;
}

🍲🍲3.那么这个时候我们想通过构造方法在子类中给color成员变量初始化,就必须先给基类中继承下来的成员变量初始化,然后初始化自己的成员变量。

class B1 extends A1{
    public String color;
    public B1(){
//  super(); // 注意子类构造方法中默认会调用基类的无参构造方法:super(),
// 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,
// 并且只能出现一次
        this.color = color;
    }
}

🍵🍵4.如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。

class A1{
    public String name;
    public int age;
    public A1(String name,int age){//此时父类构造方法是带有两个参数的
        this.age = age;
        this.name = name;
    }
}

class B1 extends A1{
    public String color;
    public B1(String name,int age){//子类构造方法必须带有明确的基类的参数,然后通过super关键字访问父类成员变量
        super(name,age);//必须卸载构造方法第一行
        this.color = color;
    }
}

☕☕5. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现。

4c3a19e5d99b46ffaa62eae1aeb49dee.png

 六、super和this比较

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

🍻🍻【不同点】
1. this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用。

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

2193da9e80a84c90b50e6c1e251bb58b.jpeg🥪🥪看个图片放松一下叭!

 七、代码块执行顺序

本小节内容只需记忆便可,想详细了解原理的可以查找其他资料哈!博主在这里不过多介绍!

🥠1、父类静态代码块优先于子类静态代码块执行,且是最早执行。
🥐2、父类实例代码块和父类构造方法紧接着执行。
🥮3、子类的实例代码块和子类构造方法紧接着再执行。
🥞4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行。

 八、final 关键字

final关键可以用来修饰变量、成员方法以及类。

🍏🍏1. 修饰变量或字段,表示常量(即不能修改)。

c70c6f8e5c7e4d25883171de2e864ccb.png

🍑🍑 2. 修饰类:表示此类不能被继承。

55c4fe3b0c5446dba21431dfbe25b0e4.png

🍒🍒3. 修饰方法:表示该方法不能被重写(后序介绍)。

版权声明:程序员胖胖胖虎阿 发表于 2022年11月6日 下午9:40。
转载请注明:【JavaSE】继承与多态(上篇) | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...