返回顶部
首页 > 资讯 > 后端开发 > Python >解析JavaSE的继承和多态
  • 859
分享到

解析JavaSE的继承和多态

2024-04-02 19:04:59 859人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录1. 继承1. 子类继承了父类,获得父类的全部Field和方法。2. 子类继承了父类,额外增加新的Field和方法3. 子类继承了父类,重写父类中的方法4. super限定,在子

1. 继承

1. 子类继承了父类,获得父类的全部Field和方法。

子类Student类继承父类,将可以获得父类的全部Field和方法

public class Person {
    public int age;
    public void show(){
        System.out.println("调用了父类中的show()方法");
    }
}
public class Student extends Person {
    public static void main(String[] args) {
        Student student = new Student();
        student.name = "张三";
        student.age=18;
        // 调用父类中的show()方法
        student.show();
    }
}

2. 子类继承了父类,额外增加新的Field和方法

继承了父类中的属性和方法,同时新增一个show1()方法

public class Person {
    public int age;
    public void show(){
        System.out.println("调用了父类中的show()方法");
    }
}
public class Student extends Person {
    public static void show1(){
        System.out.println("调用了子类中的show1()方法");
    }
    public static void main(String[] args) {
        Student student = new Student();
        // 调用父类中的show()方法
        student.show();
        // 调用子类中的show1()方法
        student.show1();
    }
}

3. 子类继承了父类,重写父类中的方法

1、这种子类包含与父类同名方法的现象被称为方法重写,也被称为方法覆盖(Override)。可以说子类重写了父类的方法,也可以说子类覆盖了父类的方法。

public class Person {
    public int age;
    public void show(){
        System.out.println("调用了父类中的show()方法");
    }
}
public class Student extends Person {
    public void show(){
        System.out.println("调用了子类中的show()方法");
    }
    public static void main(String[] args) {
        Student student = new Student();
        // 调用了子类中的show()方法
        student.show();
    }
}

2、注意:方法的重写要遵循“两同两小一大”规则

(1) “两同”即方法名相同、形参列表相同;

(2) “两小”指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;

(3) “一大”指的是子类方法的访问权限应比父类方法的访问权限更大或相等;

(4) 尤其需要指出的是,覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法,不能一个是类方法,一个是实例方法;

 public class Person {
    public int age;
    public void show(){
        System.out.println("调用了父类中的show()方法");
    }
}
public class Student extends Person {
    // 编译报错,因为父类中的show()方法不是static修饰的,子类就不能使用static修饰
    public static void show(){
        System.out.println("调用了子类中的show()方法");
    }
}

3、注意:如果父类方法具有private访问权限,则该方法对其子类是隐藏的,因此其子类无法访问该方法,也就是无法重写该方法。

如果子类中定义了一个与父类private方法具有相同的方法名、相同的形参列表、相同的返回值类型的方法,依然不是重写,只是在子类中重新定义了一个新方法。

public class Person {
    public int age;
    private void show(){
        System.out.println("调用了父类中的show()方法");
    }
}
public class Student extends Person {
    // show()方法是private方法,子类不可以访问该方法,因此可以添加static关键字
    public static void show(){
        System.out.println("调用了子类中的show()方法");
    }
}

4、注意:当子类覆盖了父类方法后,访问的便是子类中被覆盖的方法,将无法访问父类中被覆盖的方法。

4. super限定,在子类调用父类中被覆盖的方法

1、如果需要在子类方法中调用父类被覆盖的实例方法,则可使用super限定来调用父类被覆盖的实例方法。

public class Person {
    public int age;
    public void show(){
        System.out.println("调用了父类中的show()方法");
    }
}
public class Student extends Person {
    public void show(){
        System.out.println("调用了子类中的show()方法");
    }
    public void test(){
        // 调用了父类中的show()方法
        super.show();
    }
    public static void main(String[] args) {
        Student student = new Student();
        student.test();
    }
}

2、如果需要在子类方法中调用父类被覆盖的类方法,则可使用super限定来调用父类被覆盖的类方法。

public class Person {
    public int age;
    public static void show(){
        System.out.println("调用了父类中的show()方法");
    }
}
public class Student extends Person {
    public static void show(){
        System.out.println("调用了子类中的show()方法");
    }
    public void test(){
        // 调用了父类中的show()方法
        Person.show();
    }
    public static void main(String[] args) {
        Student student = new Student();
        student.test();
    }
}

3、super是Java提供的一个关键字,super用于限定该对象调用它从父类继承得到的Field或实例方法。

正如this不能出现在static修饰的方法中一样,super也不能出现在static修饰的方法中。static修饰的方法是属于类的,该方法的调用者可能是一个类,而不是对象,因而super限定也就失去了意义。

public class Person {
    public int age;
    public void show(){
        System.out.println("调用了父类中的show()方法");
    }
}
public class Student extends Person {
    public void show(){
        System.out.println("调用了子类中的show()方法");
    }
    public void test(){
        // 调用了父类中的show()方法
        super.show();
    }
    public static void main(String[] args) {
        Student student = new Student();
        student.test();
        // 编译报错,因为super不能出现在static修饰的方法中
        super.show();
    }
}

4、如果子类定义了和父类同名的Field,则会发生子类Field隐藏父类Field的情形。

在正常情况下,子类里定义的方法默认会访问到子类中定义的Field,无法访问到父类中被隐藏的Field,在子类定义的实例方法中可以通过super来访问父类中被隐藏的Field

public class Person {
    public int age=5;
}
public class Student extends Person {
    private int age = 10;
    public void getOwner(){
        System.out.println(age);
    }
    public void getBase(){
        System.out.println(super.age);
    }
    public static void main(String[] args) {
        Student student = new Student();
        // 10
        student.getOwner();
        // 5
        student.getBase();
    }
}

如果在某个方法中访问名为age的Field,但没有显式指定调用者,则系统查找a的顺序为:

(1) 查找该方法中是否有名为age的局部变量;

(2) 查找当前类中是否包含名为age的Field;

(3) 查找age的直接父类中是否包含名为age的Field,依次上溯age的所有父类,直到java.lang.Object类,如果最终不能找到名为age的Field,则系统出现编译错误。

5、子类不会获得父类的构造器,但子类构造器里可以调用父类构造器的初始化代码

(1) 在一个构造器中调用另一个重载的构造器使用this调用来完成,在子类构造器中调用父类构造器使用super调用来完成;

(2) 如果在构造器中使用super,则super用于限定该构造器初始化的是该对象从父类继承得到的Field,而不是该类自己定义的Field;

public class Person {
    public String name;
    public int age;
    public Person(String name){
        this.name = name;
    }
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
}
public class Student extends Person {
    private String color;
    // super调用的是其父类的构造器,而this调用的是同一个类中重载的构造器
    // 使用super调用父类构造器也必须出现在子类构造器执行体的第一行,所以this调用和super调用不会同时出现
    public Student(String name,int age){
        super(name);
        this.age = age;
    }
    public Student(String name,int age,String color){
        // 通过super调用父类构造器完成初始化过程
        this(name,age);
        this.color = color;
    }
    public static void main(String[] args) {
        Student student = new Student("张三",18,"红色");
    }
}

2. 多态

Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态。

public class Parent {
    public int book=10;
    public void test(){
        System.out.println("父类中的test()方法");
    }
    public void parent(){
        System.out.println("父类中的parent()方法");
    }
}
public class Sun extends Parent {
    public String book = "这是一本好书";
    public void test(){
        System.out.println("子类中的test方法");
    }
    public void sun(){
        System.out.println("子类中的sun方法");
    }
    public static void main(String[] args) {
        // 编译时类型和运行时类型一致,不存在多态
        Parent parent = new Parent();
        // 10
        System.out.println(parent.book);
        // 父类中的test()方法
        parent.test();
        // 父类中的parent()方法
        parent.parent();
        // 编译时类型和运行时类型一致,不存在多态
        Sun sun = new Sun();
        // 这是一本好书
        System.out.println(sun.book);
        // 子类中的test方法
        sun.test();
        // 子类中的sun方法
        sun.sun();
        // 编译时类型和运行时类型不一致,存在多态
        // p变量的编译时类型是Parent,而运行时类型是Sun
        Parent p = new Sun();
        // 对象的Field则不具备多态性
        // 10
        System.out.println(p.book);
        // 子类中的test方法
        p.test();
        // 父类中的parent()方法
        p.parent();
        // Parent类中没有sun()方法,编译报错
        p.sun();
    }
}

当把一个子类对象直接赋给父类引用变量时,例如上面的Parent p = new Sun();,这个p引用变量的编译时类型是Parent,而运行时类型是sun :

(1) Java允许把一个子类对象直接赋给一个父类引用变量,无须任何类型转换,这种被称为向上转型,向上转型由系统自动完成;

(2) 当调用该引用变量的test方法时,实际执行的是Sun类中覆盖后的test方法,这就是多态;当运行时调用该引用变量的方法时,其方法行为总是表现出子类方法的行为特征,而不是父类方法的行为特征,这就可能出现:相同类型的变量、调用同一个方法时呈现出多种不同的行为特征,这就是多态。

(3) 与方法不同的是,对象的Field则不具备多态性,通过引用变量来访问其包含的实例Field时,系统总是试图访问它编译时类型所定义的Field,而不是它运行时类型所定义的Field;

3. 引用变量的强制类型转换

编写Java程序时,引用变量只能调用它编译时类型的方法,而不能调用它运行时类型的方法,如果需要让这个引用变量调用它运行时类型的方法,则必须把它强制类型转换成运行时类型。

(1) 基本类型之间的转换只能在数值类型之间进行,这里所说的数值类型包括整数型、字符型和浮点型。但数值类型和布尔类型之间不能进行类型转换。

(2) 引用类型之间的转换只能在具有继承关系的两个类型之间进行,如果是两个没有任何继承关系的类型,则无法进行类型转换,否则编译时就会出现错误。

考虑到进行强制类型转换时可能出现异常,因此进行类型转换之前应先通过instanceof运算符来判断是否可以成功转换。

(1) instanceof运算符的前一个操作数通常是一个引用类型变量,后一个操作数通常是一个类或者接口,它用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。如果是,则返回true,否则返回false;

(2) 在使用instanceof运算符时需要注意:instanceof运算符前面操作数的编译时类型要么与后面的类相同,要么与后面的类具有父子继承关系,否则会引起编译错误;

(3) instanceof运算符的作用是:在进行强制类型转换之前,首先判断前一个对象是否是后一个类的实例,是否可以成功转换,从而保证代码更加健壮;

(4) instanceof和(type)是Java提供的两个相关的运算符,通常先用instanceof判断一个对象是否可以强制类型转换,然后再使用(type)运算符进行强制类型转换,从而保证程序不会出现错误;

public class Main {
    public static void main(String[] args) {
        Object object = "hello";
        if(object instanceof String){
            String s = (String) object;
        }
    }
}

4. 面试

1、Java中实现多态的机制是什么?

Java中的多态靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

2、谈谈你对多态的理解?

多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在程序运行期间才能决定。

因为在程序运行时才确定具体的类,这样,不用修改源代码,就可以让引用变量绑定到各种不同的对象上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!  

--结束END--

本文标题: 解析JavaSE的继承和多态

本文链接: https://lsjlt.com/news/141077.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 解析JavaSE的继承和多态
    目录1. 继承1. 子类继承了父类,获得父类的全部Field和方法。2. 子类继承了父类,额外增加新的Field和方法3. 子类继承了父类,重写父类中的方法4. super限定,在子...
    99+
    2024-04-02
  • 继承和多态
    在OOP程序设计中,当定义一个class的时候,可从某个现有的class继承 新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class) 格式:   class...
    99+
    2023-01-31
    多态
  • Java中继承和多态的示例分析
    这篇文章给大家分享的是有关Java中继承和多态的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言首先我们如果要使用Java中存在的包,可以程序中使用import语句导入包。包说通俗点就是一个文件夹,为了...
    99+
    2023-06-20
  • Java中封装、继承和多态的示例分析
    这篇文章主要介绍Java中封装、继承和多态的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!封装所谓的封装就是把类的属性和方法使用private修饰,不允许类的调用者直接访问,我们定义如下一个类,可以看到所有的...
    99+
    2023-06-15
  • Python中的继承和多态是什么
    这篇文章主要讲解了“Python中的继承和多态是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python中的继承和多态是什么”吧!一、继承的介绍继承是一种创建新的类的方式,新创建的叫子...
    99+
    2023-06-15
  • python中的继承和多态怎么用
    本篇内容介绍了“python中的继承和多态怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、继承的介绍继承是一种创建新的类的方式,新创...
    99+
    2023-06-28
  • Java超详细讲解继承和多态的使用
    目录继承和多态1、继承1.1、继承概念1.2、继承的语法1.3、父类成员的访问1.31、子类和父类不存在同名成员变量1.32、子类和父类成员变量同名1.33、成员方法名字不同1.34...
    99+
    2024-04-02
  • C++ 虚拟函数与继承:理解多态继承中的奥秘
    虚拟函数和继承在面向对象编程中实现多态性:声明虚拟函数允许派生类重写基类方法,并根据对象的运行时类型调用。继承建立类层次,派生类可访问和扩展基类数据和方法。多态继承允许派生类从多个基类继...
    99+
    2024-04-28
    c++ 多态
  • 深入浅析java中面向对象的继承和多态
    深入浅析java中面向对象的继承和多态?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。继承和多态一.this super关键字this: 可以在构造器中的第一代码中...
    99+
    2023-05-31
    java 继承 多态
  • Python的类、继承和多态简单介绍
    这篇文章主要讲解了“Python的类、继承和多态简单介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python的类、继承和多态简单介绍”吧!类的定义假如要定义一个类 Point,表示二维...
    99+
    2023-06-17
  • Python中类继承与多态的示例分析
    这篇文章主要介绍了Python中类继承与多态的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。概念类(Class): 用来描述具有相同的属性和方法的对象的集合。类变量:...
    99+
    2023-06-22
  • python3:面向对象(多态和继承、方
    1、多态 同一个方法在不同的类中最终呈现出不同的效果,即为多态。 class Triangle: def __init__(self,width,height): self.width = width ...
    99+
    2023-01-31
    面向对象 多态
  • Java 多态中继承的转型详解与用法分析
    目录一、前言二、转型向上转型向下转型三、instanceof运算符instanceof的用处instanceof的使用格式:一、前言 前面我们学习了多态的概述和使用,现在我们来学习前...
    99+
    2024-04-02
  • Python类中的单继承和多继承用法
    本篇内容主要讲解“Python类中的单继承和多继承用法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python类中的单继承和多继承用法”吧!前言Python面向对象编程语言,有List、Str...
    99+
    2023-06-02
  • C++多继承(多重继承)的实现
    在前面的例子中,派生类都只有一个基类,称为单继承(Single Inheritance)。除此之外,C++也支持多继承(Multiple Inheritance),即一个派生类可以有...
    99+
    2023-05-16
    C++多继承 C++多重继承
  • 解锁 JavaScript 继承的潜力:理解虚函数和多态性
    ...
    99+
    2024-04-02
  • JavaScript继承与多继承实例讲解
    这篇文章主要介绍“JavaScript继承与多继承实例讲解”,在日常操作中,相信很多人在JavaScript继承与多继承实例讲解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2024-04-02
  • 深入解析Python多继承的机制
    深入探讨Python中的多继承机制引言:在Python中,多继承是一种强大而灵活的机制。通过多继承,我们可以在一个类中同时集成多个父类的属性和方法,大大增强了类的功能。多继承的基本概念多继承,即一个子类可以同时继承多个父类的属性和方法。这种...
    99+
    2023-12-30
    Python 机制 多继承
  • Java初学者入门之继承和多态
    前言 首先我们如果要使用Java中存在的包,可以程序中使用import语句导入包。包说通俗点就是一个 文件夹,为了方便管理。 在程序中声明包的语法: package <包名&...
    99+
    2024-04-02
  • C++关于指针,继承和多态介绍
    目录指针指针和继承指针、继承和多态指针 我们在书本上学到的指针基本上都是:首先,指针是一个变量;其次,这个变量存储的值是一个地址。这个是对指针的一个基本理解,最近在编程中发现了一些新...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作