你真的熟悉Java中的继承与多态?给你几分钟能回答上来

  • 如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错.所以呢,一般情况下,最好能为每个类提供一个无参构造方法,以便于对该类进行扩展,同时避免错误。
  • 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则**必须显式的使用"super.属性"**的方式,表明调用的是父类中声明的属性。
  • 特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。

public class Person {
private String name;
private int age;
private Date birthDate;
public Person(String name, int age, Date d) {
this.name = name;
this.age = age;
this.birthDate = d; }
public Person(String name, int age) {
this(name, age, null);
}
public Person(String name, Date d) {
this(name, 30, d);
}
public Person(String name) {
this(name, 30);
}
}

public class Student extends Person {
private String school;
public Student(String name, int age, String s) {
super(name, age);
school = s; }
public Student(String name, String s) {
super(name);
school = s; }
// 编译出错: no super(),系统无法调用父类无参数的构造器。
//There is no default constructor available in ‘chapter01.Person’
public Student(String s) {
school = s; }
}

2.2 构造方法链

在任何情况下,构造一个类的实例时,将会调用沿着继承链的所有父类的构造方法当构造一个子类的对象时,子类构造方法会在完成自己的任务之前,首先调用它的父类的构造方法。如果父类继承自其他类,那么父类构造方法又会在完成自己的任务之前,调用它自己的父类的构造方法。这个过程持续到沿着这个继承体系结构的最后一个构造方法被调用为止。这就是构造方法链(constructor chaining)。

public class Faculty extends Employee {
public static void main(String[] args) {
Faculty faculty = new Faculty();
}

public Faculty() {
System.out.println(“(4) Performs Faculty’s tasks”);
}
}

class Employee extends Person {
public Employee() {
this(“(2)Invoke Employee’s overloaded constructor”);
System.out.println("(3)Performs Employee’s tasks ");
}

public Employee(String s) {
System.out.println(s);
}
}

class Person {
public Person() {
System.out.println(“(1) Performs Person’s tasks”);
}
}

结果:

在第3 行,new Faculty() 调用Faculty 的无参构造方法。由于 Faculty 是 Employee 的子类,所以,在Faculty 构造方法中的所有语句执行之前,先调用 Employee 的无参构造方法。Employee 的无参构造方法调用Employee 的第二个构造方法(第13 行)。由于 Employee 是 Person 的子类,所以,在 Employee 的第二个构造方法中所有语句执行之前,先调用 Person 的无参构造方法。

2.3 调用父类的方法

super.方法名(参数);

3.方法重写

子类从父类中继承方法。有时,子类需要修改父类中定义的方法的实现,这称作方法重 写(method overriding),:要重写一个方法,需要在子类中使用和父类一样的签名以及一样的返回值类型来对该方法进行定义。

注意以下几点:

  1. 仅当实例方法是可访问时,它才能被覆盖。因为私有方法在它的类本身以外是不能访问的,所以它不能被覆盖。如果子类中定义的方法在父类中是私有的,那么这两个方法完全没有关系。
  2. 子类不能用语法 super.super.toStringO 访问父类的父类中的toString ,这是一个语法错误。
  3. 与实例方法一样,静态方法也能被继承。但是,静态方法不能被覆盖。如果父类中定义的静态方法在子类中被重新定义,那么在父类中定义的静态方法将被隐藏。可以使用语法:父类名 .静态方法名(SuperClassName.staticMethodName) 调用隐藏的静态方法。

这个再次详细说明一下

public class StaticExtends {

public static void main(String[] args) {
//声明为Father类,son1静态方法和Father类绑定
Father son = new Son();

son.method();
son.staticMethod();

Son son2 = new Son();
son2.method();
son2.staticMethod();
}
}

class Father {

void method() {
System.out.println(“父类方法”);
}

static void staticMethod() {
System.out.println(“父类静态方法”);
}
}

class Son extends Father {

@Override
void method() {
System.out.println(“子类方法”);
}

static void staticMethod() {
System.out.println(“子类静态方法”);
}
}

输出结果:

在子类中重写父类的static方法,是不会报错的,编译也可以通过,但是在通过一个声明为父类,实际类型为子类的引用变量调用该方法时,发现被调用的仍是父类中原本以为会被覆盖的方法,不具有“多态”特性。所以呢,父类的static方法是不会被重写的。

4.Object类及其常用方法

Java 中的所有类都继承自 java.lang.Object 类,如果在定义一个类时没有指定继承性,那么这个类的父类就被默认为是 Object。

4.1 toString()方法

Object 类中toString()方法的默认实现是:

public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}

调用一个对象的 toString() 会返回一个描述该对象的字符串。默认情况下,它*返回一个由该对象所属的类名、at 符号(@)以及该对象十六进制形式的内存地址组成的字符串。*这个信息不是很有用,所以重写。

  • 像String、Date、File、包装类等都重写了Object类中的toString()方法。使得在调用对象的toString()时,返回"实体内容"信息。
  • 可以根据需要在用户自定义类型中重写toString()方法。 如String 类重写了toString()方法,返回字符串的值。

s1=“hello”;
System.out.println(s1);//相当于System.out.println(s1.toString());

  • 基本类型数据转换为String类型时,调用了对应包装类的toString()方法

int a=10;
System.out.println(“a=”+a);

4.2 equals()方法

Object 类中 equals 方法的默认实现是:

public boolean equals(Object obj) {
return (this obj);
}

说明:Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体。

  • 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
  • 通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们 就需要对Object类中的equals()进行重写。重写的原则:比较两个对象的实体内容是否相同

tips:==和equals的区别:

  • 1 = 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型 就是比较内存地址
  • 2 equals的话,它是属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也是;我们可以看到String等类的equals方法是被重写过的,而且String类在日常开发中用的比较多,久而久之,形成了equals是比较值的错误观点。
  • 3 具体要看自定义类里有没有重写Object的equals方法来判断。
  • 4 通常情况下,重写equals方法,会比较类中的相应属性是否都相等。

二. 多态

5.1 介绍

首先呢,我们知道继承关系使一个子类继承父类的特征,并且附加一些新特征。子类是它的父类的特殊化,每个子类的实例都是其父类的实例,但是反过来就不成立。例如:每个圆都是一个几何对象,但并非每个几何对象都是圆。因此,总可以将子类的实例传给需要父类型的参数。使用父类对象的地方都可以使用子类的对象。这就是通常所说的多态。简单来说,多态意味着父类型的变量可以引用子类型的对象。

5.2 动态绑定

我们都知道方法可以在父类中定义而在子类中重写。(方法可以在沿着继承链的多个类中实现。JVM 决定运行时调用哪个方法。)那么

最后

由于篇幅原因,就不多做展示了

[外链图片转存中…(img-gYWYuX1y-1714574042949)]

[外链图片转存中…(img-LkaKKdyj-1714574042949)]

[外链图片转存中…(img-GBEaLq4Y-1714574042949)]

[外链图片转存中…(img-W5TjzLzx-1714574042950)]

[外链图片转存中…(img-kRN9EFHU-1714574042950)]

由于篇幅原因,就不多做展示了

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多态性是指在面向对象编程,一个对象可以以多种不同的方式呈现。在Java,最常见的多态发生在使用父类的引用来引用子类的对象。这意味着可以使用父类类型的引用来调用子类类型的方法。通过多态性,可以增强代码的灵活性和可扩展性。 在Java实现多态有两个关键点:继承和方法重写。首先,需要创建一个父类并定义一个抽象方法,这样可以确保子类需要实现该方法。然后,创建子类并重写父类的抽象方法,实现子类自己的逻辑。 举个例子,假设有一个抽象类Animal,其有一个抽象方法eat()。然后创建两个子类Dog和Cat,它们分别重写了eat()方法。在使用时,可以使用Animal类型的引用来引用Dog或Cat的对象,然后调用eat()方法。这样就实现了多态性。 代码示例的Test类展示了如何实现多态。首先,创建了一个Animal类型的引用an1,指向Dog的对象。然后调用了an1的eat()方法,它会调用Dog类重写的eat()方法。同样的,创建了一个Animal类型的引用an2,指向Cat的对象,然后调用了an2的eat()方法,它会调用Cat类重写的eat()方法。 总结来说,多态性是通过继承和方法重写实现的,它可以提高代码的灵活性和可扩展性。在Java多态性最常见的表现是使用父类的引用来引用子类的对象。这样可以根据实际情况调用子类的方法,实现不同的行为。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java多态概念、实现原理详解](https://download.csdn.net/download/weixin_38672840/12782475)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Java多态的概念及简单实现](https://blog.csdn.net/weixin_47861286/article/details/125925026)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值