JavaSE:继承和多态(上篇)

目录

一、前言

二、继承

(一)继承概念

 (二)继承的语法

(三)父类成员访问

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

1.1子类和父类不存在同名成员变量

 1.2子类和父类成员变量同名

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

(四)super关键字

(五)子类构造方法

(六)super和this

(七)代码块执行顺序

(八)final关键字

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

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

3. 修饰方法:表示该方法不能被重写

三、总结


一、前言

各位小伙伴们大家好,今天蜡笔小欣将继续带来大家一起去遨游Java的知识海洋世界,掌握Java中的继承。话不多说,开始我们今天的学习。

二、继承

public class Dog {
    String name;
    int age;
    float weight;
    public void eat() {
        System.out.println(name + "正在吃饭");
    }
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
    public void bark() {
        System.out.println(name + "汪汪汪");
    }
}

public class Cat{
    String name;
    int age;
    float weight;
    public void eat(){
        System.out.println(name + "正在吃饭");
    }
    public void sleep()
    {
        System.out.println(name + "正在睡觉");
    }
    public void mew(){
        System.out.println(name + "喵喵喵~~~");
    }
}

上面这个Dog类和Cat类有大量重复的部分,我们可以将这些共同点共性抽取,放在一个Animal类,进而实现代码复用。

(一)继承概念

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

 (二)继承的语法

Java 中如果要表示类之间的继承关系,需要借助 extends 关键字,具体如下:
修饰符 class 子类 extends 父类 {
// …
}

因此我们可以创建一个Animal类,将Dog类和Cat类的共同点放在Animal类里面,具体代码如下:

class Animal{
    String name;
    int age;
    float weight;
    public void eat(){
        System.out.println(name + "正在吃饭");
    }
    public void sleep(){
        System.out.println(name + "正在睡觉");
    }
}

 我们再通过继承,让Dog类和Cat类继承Animal类里面的成员变量和方法,具体修改如下:

class Animal {
    String name;
    int age;
    float weight;

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

    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}

class Dog extends Animal {
    public void bark() {
        System.out.println(name + "汪汪汪");
    }
}

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

Tips:

1. 子类会将父类中的成员变量或者成员方法继承到子类中,

2.子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承。

(三)父类成员访问

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

1.1子类和父类不存在同名成员变量
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
    }
}
 1.2子类和父类成员变量同名
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; // 编译失败,因为父类和子类都没有定义成员变量d
    }
}
结论:
在子类方法中或者通过子类对象访问成员时
1.如果访问的成员变量子类中有,优先访问自己的成员变量。
2.如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
3.如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
4. 成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找

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

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

2.通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。

3.通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同 ( 重载 ) ,根据调用方法适传递的参数选择合适的方法访问,如果没有则报错。

(四)super关键字

Java给我们 提供了 super 关键字,该关键字主要作用:在子类方法中访问父 类的成员。
super的三个用法:
1.super.成员变量; 访问父类普通成员变量
2.super.方法(); 访问父类普通成员方法
3.super (); 调用父类的构造方法

下面我举个例子,让大家更好地理解:

我们先定义一个父类Student类,具体代码如下:

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

接着我们定义子类Stu继承父类Student ,在这个子类里有自己的成员变量和方法,具体代码如下:

public class Stu extends Student {
    public String name;//与父类中的成员变量同名且类型相同
    public double age;//与父类中的成员变量同名但类型不相同

    public void method1(int a) {
        System.out.println("这是Stu类中的method1方法");
    }

    public void method3() {
        name = "张三";//对于同名的成员变量,直接访问时,访问的都是子类
        age = 20;
        super.name = "李四";//访问父类的成员变量时,需要借助super关键字
        super.age = 18;//super是获取子类对象中从父类继承下来的部分

        //父类和子类中构成重载的方法
        method1();//访问父类的method1方法
        method1(10);//访问子类中带一个参数的method1方法
    }
}

使用super关键字时要注意:

1.只能在非静态方法中使用,

2.在子类方法中,访问父类的成员变量和方法,
3.对于父类的private成员变量,子类会继承继承该成员变量,但不可以访问,
4.java不支持多继承,即一个类只能继承一个父类。

(五)子类构造方法

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

下面给大家演示一下:

class Student {
    public String name;
    public int age;
    public void study() {
        System.out.println("正在学习");
    }
}

我们首先定义一个父类Student,包含两个成员变量和一个成员方法。

public class Stu extends Student {
    public String gender;
}

紧接着我们再定义一个子类Stu继承自父类Student,子类中新增一个成员变量gender。

public class Stu extends Student {
    public String gender;
    public Stu() {
        this.gender = gender;
    }
}

当我们想通过构造方法在子类中给gender成员变量初始化,就必须先给基类中继承下来的成员变量初始化,然后初始化自己的成员变量。

class Student {
    public String name;
    public int age;

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

    public void study() {
        System.out.println("正在学习");
    }
}

public class Stu extends Student {
    public String gender;

    //子类构造方法必须带有明确的基类的参数,然后通过super关键字访问父类成员变量
    public Stu(String name, int age) {
        super(name, age);//super必须写在构造方法的第一行
        //this(name,age);//super()和this()不能同时出现
        this.gender = gender;
    }
}

当父类的构造方法带有参数,那我们需要给子类显式定义构造方法,并且在子类的构造方法中选择合适的父类构造方法进行调用,否则会编译失败。

(六)superthis

super和this的共同点:

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


super和this的不同点:

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

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

(七)代码块执行顺序

我们通过下面这个代码来了解继承关系上代码块的执行顺序。


class Student {
    public String name;
    public int age;

    public Student(String name, int age) {//父类的构造方法是带有两个参数的
        this.name = name;
        this.age = age;
        System.out.println("Student:构造方法执行");
    }

    {
        System.out.println("Student:实例代码块执行");
    }

    static {
        System.out.println("Student:静态代码块执行");
    }
}

class Stu extends Student {
    public Stu(String name, int age) {
        super(name, age);
        System.out.println("Stu:构造方法执行");
    }

    {
        System.out.println("Stu:实例代码块执行");
    }

    static {
        System.out.println("Stu:静态代码块执行");
    }
}

public class Test {
    public static void main(String[] args) {
        Stu student1 = new Stu("张三", 19);
        System.out.println("===========================");
        Stu student2 = new Stu("李四", 20);
    }

    public static void main1(String[] args) {
        Student student3 = new Student("王五", 10);
        System.out.println("============================");
        Student student4 = new Student("赵六", 20);
    }
}

运行结果如下:

 

Tips:

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

(八)final关键字

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

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

public class Test {
    public static void main(String[] args) {
        final int age = 18;
        age=20;//编译错误
    }
}

由于变量age被final修饰,导致变量age变为常量,修改不了。 

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

final class Person {
    public String name;
    public int age;
}
class Student extends Person {//编译错误,无法继承Person类
    public void study() {
        System.out.println("正在学习!");
    }
}

上面代码的父类Person被final修饰,导致子类Student无法继承Person,无法继承父类中的成员变量。 

3. 修饰方法:表示该方法不能被重写

class Person {
    public String name;
    public int age;

    final void eat() {
        System.out.println("正在吃饭!");
    }
}

class Student extends Person {//编译错误,无法继承Person类

    public void eat() {//编译错误,无法重写eat方法
        System.out.println("正在吃面包");
    }

    public void study() {
        System.out.println("正在学习!");
    }
}

 因为父类Person中的eat方法被final修饰,导致子类Student不能对eat方法进行重写,所以编译错误。

三、总结

继承允许一个类(子类)继承另一个类(父类)的属性和方法。通过继承,子类可以获得父类的属性和方法,同时还可以定义自己的属性和方法,从而实现代码的复用和扩展。继承的关键字是extends,子类通过extends关键字来继承父类。通过继承,子类可以重写父类的方法,从而实现多态性。此外,Java中只支持单继承,即一个类只能有一个直接的父类,但可以有多个间接的父类。继承可以帮助我们更好地组织和管理代码,实现代码的层次结构,使代码更加清晰和易于理解。但如果我们过度使用继承也会导致代码的耦合性增加,不利于代码的重构和扩展。

以上就是本期分享的全部内容,希望本期的内容能够对大家有所帮助,下次蜡笔小欣再跟大家分享Java中多态的知识点,感谢大家的支持与鼓励,我们下次再见!

  • 55
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 36
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值