面向对象特征之继承

}

// 子类不能重写父类的final方法,否则编译期异常

// ‘test()’ cannot override ‘test()’ in ‘extendsTest.Super’; overridden method is final

// @Override

// public void test(){

// System.out.println(“Base try to override Super final method”);

// }

}

思考题

===

1.Java的继承体系都是单继承吗?


不是。

Java的类的继承体系都是单继承。

但是

Java的接口的继承体系时多继承,即一个接口可以继承多个其他接口。

2.Java的类不是单继承吗,比如A继承B,但是B中并没有定义equals,toString等方法,为什么A类对象还是可以调用这些方法?


Java类的继承体系是单继承。即一个类只能由一个父类。

且继承发生后,子类可以继承父类的所有成员变量,成员方法,内部类,枚举类。

但是Java继承还有一个规则:

如果一个类没有显式继承其他类,则默认继承java.lang.Object类

举个例子

A extends B

B extends C

C extends D

D 没有显式继承任何其他类

分析:

由于D没有显式继承其他类,所以D默认继承Object类。所以D获得Object类的所有成员方法(equals,toString等)

而C继承了D,所以C也获得了(equals,toString)

而B继承C,所以B也获得了(equals,toString)

同理A最终也能获得(equals,toString)

总结:Java中类的继承是单继承,只能说明一个类只能由一个直接父类,但是可以由多个间接父类。

3.子类为什么不能继承父类的构造器和初始化块?


我们知道构造器的名字必须和类名相同。

而子类继承自父类的成员的名字不会改变。所以构造器不能被继承,因为继承自父类的构造器和子类类名冲突。

另外,初始化块在本质上是属于构造器的一部分。在代码编译后,初始化块就会消失,初始化块中的代码会融入到构造器中,且在原先构造器执行体代码前。

4.子类构造器中使用super关键字可以调用父类构造器,会导致产生父类对象吗?


不会。

在子类构造器中使用super调用父类构造器,只是为了给子类对象中(继承自父类的实例变量)完成初始化。不会产生父类对象。

5.子类不会继承父类的构造器和初始化块,我们知道构造器可以用super调用,那么父类的初始化块,子类怎么调用?


首先我们需要知道初始化块是无法被外界调用的,它只在类加载时(静态初始化块),或创建对象时(实例初始化块)执行一次。

另外我们知道 构造器执行前,总会先执行实例初始化块。

所以当我们用super调用父类构造器时,父类构造器会默认先调用实例初始化块。

6.子类是否可以继承父类final修饰的实例变量,和实例方法?


public class Main{

public static void main(String[] args){

Base b = new Base();

b.test();

System.out.println(b.num);

}

}

class Super{

final int num = 10;

final void test(){

System.out.println(“Super final method”);

}

}

class Base extends Super{}

首先运行上面的程序发现,正常运行,结果是

Super final method

10

所以子类可以继承父类的final方法和变量。

对于final关键字的作用:

1.被final修饰的类无法派生子类

2.被final修饰的变量,不能改变指向

3.被final修饰的方法,不能被子类重写。

所以子类只是不能重写父类final方法,也不能继承自父类的final变量的指向

7.子类是否可以继承父类的私有成员?


更具继承定义来看:

子类可以继承父类(除构造器,初始化块)的所有成员。

没有提到私有成员,所以子类继承了父类的私有成员的。只是子类无法访问继承自父类的私有成员而已。

这里可以将继承分为两种:

显式继承:可以访问从父类继承到的成员。

隐式继承:无法访问从父类继承到的成员。

8.子类可以将父类的静态方法重写为实例方法吗?


不可以

方法重写有一个规则:

父类实例方法只能被子类实例方法重写。

对于父类静态方法,存不存在重写规则,尚存争议。更不要说被子类实例方法重写。

另外,父类静态方法属于父类本身,在内存中只有一份。即使被子类继承,子类也不会像为(继承自父类的实例变量)单独开辟一个内存存储,而是会直接访问父类的静态方法。

9.当子类定义了和父类相同的实例变量时,父类的实例变量会被覆盖吗?


不会。子类只会隐藏继承自父类的同名实例变量。

因为子类继承父类后,创建子类对象时,会开辟两块内存空间:

一块用于存储子类本身的实例变量

一块用于存储继承自父类的实例变量

所以在内存上来看,子类实例变量和继承自父类的实例变量不会发生覆盖现象。

10.子类从父类继承的方法是否可以操作子类自定义的变量?请思考下面代码运行结果(好玩的题目,让我认识到自己对继承的了解还不够深入)


public class Main{

public static void main(String[] args){

A a = new A();

a.printOut();// A.i相加 A:1

B b = new B();

b.printOut();// B.i相加 A:0

b.show();// 2

a = b;

a.printOut();// B.i相加 A:0

}

}

class A {

int i = 0;

public void doAdd(){

i++;

System.out.println(“A.i相加”);

}

public void printOut(){

this.doAdd();

System.out.println(“A:”+i);

}

}

class B extends A {

public int i = 0;

public void doAdd(){

i+=2;

System.out.println(“B.i相加”);

}

public void show(){

System.out.println(i);

}

}

结论:子类继承的方法,只能操作子类继承的成员变量。

11.super关键字与this关键字的区别是什么,它们之间是什么关系?


主要是用途上的区别

this的用途

1.在实例方法中 代表 调用该实例方法的对象。可以用来调用本类其他实例方法。

2.在构造器中 代表 当前创建对象。 可以用来区别同名变量是形参还是对象的实例变量。

3.在构造器中 调用 其他重载的构造器。

super的用途

1.作为对象,限定该对象调用它从父类继承得到的实例变量,实例方法

2.作为构造器,限定该构造器初始化的是该对象从父类继承得到的实例变量,而不是自己的实例变量

当this和super在构造器中使用时,他们不能同时出现。

因为它们都要定义在构造器的第一行。

12.为什么说子类构造器总会调用一次父类构造器?


如果子类中只定义了一个构造器,则有三种情况:

class Base{

Base(){

// 什么都不写,系统自动隐式调用父类无参构造器

//super();// super()是显式调用父类无参构造器

//super(12);// super(12)是显式调用父类有参构造器

}

}

显然,此时肯定会调用父类构造器

如果子类中定义了多个重载构造器:

那么如果多个重载构造器中没有使用this互相引用,那么每个构造器都是默认调用super,或者显式调用super

最后

本人分享一下这次字节跳动、美团、头条等大厂的面试真题涉及到的知识点,以及我个人的学习方法、学习路线等,当然也整理了一些学习文档资料出来是给大家的。知识点涉及比较全面,包括但不限于前端基础,HTML,CSS,JavaScript,Vue,ES6,HTTP,浏览器,算法等等

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

前端视频资料:
写,系统自动隐式调用父类无参构造器

//super();// super()是显式调用父类无参构造器

//super(12);// super(12)是显式调用父类有参构造器

}

}

显然,此时肯定会调用父类构造器

如果子类中定义了多个重载构造器:

那么如果多个重载构造器中没有使用this互相引用,那么每个构造器都是默认调用super,或者显式调用super

最后

本人分享一下这次字节跳动、美团、头条等大厂的面试真题涉及到的知识点,以及我个人的学习方法、学习路线等,当然也整理了一些学习文档资料出来是给大家的。知识点涉及比较全面,包括但不限于前端基础,HTML,CSS,JavaScript,Vue,ES6,HTTP,浏览器,算法等等

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

[外链图片转存中…(img-Sc1HIJ50-1714772186078)]

前端视频资料:

  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值