我是靠谱客的博主 壮观时光,最近开发中收集的这篇文章主要介绍牛客3(1.接口的实现2.子类的初始化),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目:如果一个接口Cup有个方法use(),有个类SmallCup实现接口Cup,则在类SmallCup中正确的是()

A.void use(){...}
B.protected void use(){...}
C.public void use(){...}
D.以上语句都可以用在类SmallCup中

答案:C

解析:

既然是实现接口,就要实现接口的所有方法,相当于重写所有的方法,并且需要满足:三同一大一小(方法名,返回值类型,形参相同;访问权限>=重写前,抛出异常<=重写前)

首先明确:

  1. 接口中的方法都是隐式抽象的,会被隐式指定为public abstract (只能是public abstract的,其他修饰符都会报错)。接口中的方法是不能在接口中实现的,只能在实现接口的类汇中来实现接口中的方法。
  2. 接口中的变量会被隐式指定为public static fianl
  3. 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。

重写接口中的方法,访问权限一定是public


题目二:下面的代码输出是什么?

public class Base
{
private String baseName = "base";
public Base()
{
callName();
}
public void callName()
{
System. out. println(baseName);
}
static class Sub extends Base
{
private String baseName = "sub";
public void callName()
{
System. out. println (baseName) ;
}
}
public static void main(String[] args)
{
Base b = new Sub();
}
}

答案:A

解析:

new Sub()**在创造派生类的过程中首先创建基类对象,然后才能创建派生类。**创建基类即默认调用Base()方法,在方法中调用callName()方法,由于派生类中存在此方法,则被调用的callName()方法是派生类中的方法,此时派生类还未构造,所以baseName的值为null。

补充下类的加载顺序:

  1. 父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)
  2. 子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)
  3. 父类非静态代码块(包括费静态初始化块,非静态属性)
  4. 父类构造函数
  5. 子类非静态代码块(包括非静态初始化块,非静态属性)
  6. 子类构造函数

其中:类中静态块按照声明顺序执行,并且1,2不需要调用new类实例的时候就执行了(意思就是在类加载到方法区的时候执行的)。其次,需要理解子类覆盖父类方法的问题,也就是方法重写实现多态的问题。

Base b = new Sub();是多态的一种表现形式,声明是Base,实现是Sub类(这里不要忘了,编译看左边,运行看右边),理解为b编译时变现为Base类特性,运行时表现为Sub’类特性。当子类覆盖了父类的方法后,父类的方法已经被重写,题目中 父类初始化调用的方法为子类实现的方法,子类实现的 方法中调用的baseName为子类中的私有属性。

这个程序只执行到了步骤4,子类非静态代码块和初始化步骤还没有到,子类中的baseName还没有被初始化,所以此时baseName为空,即null。

执行方法时,由于多态表现为子类特性(运行看右边),所以会先在子类看是否有callName()方法,而此时子类未被初始化-null(执行完父类构造器后才会开始执行子类)。

最后

以上就是壮观时光为你收集整理的牛客3(1.接口的实现2.子类的初始化)的全部内容,希望文章能够帮你解决牛客3(1.接口的实现2.子类的初始化)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部