#在千锋“逆战”学习第17天# final修饰符,接口,Question7、8习题

总结

final

概念:最后的、不可更改的

final修饰类:此类不可被继承

final修饰方法:方法可以被继承,但是不可以被覆盖。

final修饰变量:此变量值不能被改变(无初始值,只允许赋值一次)

final修饰变量赋值的方法:

局部常量:显示初始化

实例常量:显示初始化,动态代码块,构造方法(注意,如果在构造方法中为实例常量赋值,必须保证所有构造方法都能对其正确赋值)

静态常量:显式初始化,静态代码块

基本数据类型常量:值不可变

引用数据类型常量:地址不可变

接口

概念:接口相当于特殊的抽象类,定义方式、组成部分与抽象类类似

使用interface定义接口 ex:interface 接口名{}

接口没有构造方法,不能创建对象。

接口中只能定义公开静态常量和公开抽象方法

接口与抽象类的异同

相同

可编译成字节码文件(.class)

不能创建对象

可以作为引用类型

具备Object中所定义的方法

不同

所有属性都是公开静态常量,隐式使用public static final修饰

所有方法都是公开抽象方法,隐式使用public abstract修饰

没有构造方法,动态代码块,静态代码块

微观概念:接口是一种能力和约定

接口的定义是代表了某种能力

方法的定义是对能力的具体要求

经验:Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口扩充子类能力。

接口支持多实现,可为类扩充多种能力

接口的规范

任何类在实现接口时,必须实现接口中的所有方法,否则此类为抽象类

实现接口中的抽象方法时,修饰符必须为public

接口的引用

同父类一样,接口也可声明引用,并指向实现类对象

注意:仅可调用接口中所声明的方法,不可调用实现类中独有的方法

可强转为实现类本身,进行独有的方法调用

---------------------------------------------------------------我是作业分割线

Q7

7.(final 属性的初始化)有如下代码

1)class MyClass{

2)final int value;

3)public MyClass(){}

4)public MyClass(int value){

5)this.value = value;

6)}

7)}

8)public class TestMain{

9)public static void main(String args[]){

10)MyClass mc = new MyClass(10);

11)System.out.println(mc.value);

12)}

13)}

选择正确答案:

A.编译通过,输出 10

B.编译不通过,把第 2 行改为 final int value = 10;

C.编译不通过,把第 3 行改为 public MyClass(){ value = 10; }

答案:C 如果在构造方法中为实例常量赋值,必须保证所有构造方法都能对其正确赋值

8.(final 变量)有如下代码 class MyClass {

public void printValue(final int value){

System.out.println(value);

}

public void changeValue(int value){

value = value * 2;

System.out.println(value);

}

}

public class TestMain{

public static void main(String args[]){

MyClass mc = new MyClass();

int value = 5;

final int fvalue = 10;

mc.printValue(value); //1

mc.printValue(fvalue); //2

mc.changeValue(value); //3

mc.changeValue(fvalue);//4

}

}

选择正确答案

A.编译通过

B.//1 出错

C.//2 出错

D.//3 出错

E.//4 出错

答案:E 因为实例常量的值不可以被改变

9.(final 修饰引用)有如下代码 class MyValue{

int value;

}

public class TestFinal{

public static void main(String args[]){

final MyValue mv = new MyValue();

mv.value = 100;

//1

System.out.println(mv.value);

}

}

下面说法正确的是:

A. 编译不通过 。

B. 编译通过。在//1 处加上:mv.value = 200; 则编译不通过

C. 编译通过。如果在//1 处加上:mv = new MyValue(); 则编译不通过。

答案:C

引用类型常量地址不可改变,里面的值可以改变。

10.(final 方法,方法覆盖)有如下代码 class Super{

public final void m1(){

System.out.println(“m1() in Super”);

}

public void m1(int i){

System.out.println(“m1(int) in Super”);

}

}

class Sub extends Super{ public void m1(int i){

System.out.println(“m1(int) in Sub”);

}

public void m1(double d){ System.out.println(“m1(double) in Sub”);

}

}

public class TestMain{

public static void main(String args[]){

Sub s = new Sub();

s.m1();

s.m1(10);

s.m1(1.5);

}

}

答案:
m1() in Super
m1(int) in Sub
m1(double) in Sub

13.(修饰符综合)下列方法声明中正确的是:

A.abstract final void m()

B.public void final m()

C.static abstract void m()

D.private final void m()

E.private abstract void m()

F.public static final void m()

答案:DF

A不对是因为abstract修饰的方法就是让子类重写,但是final修饰的不让子类重写

B不对,修饰符的顺序 方法修饰符 返回值类型 方法名(){} void与final位置不对, B的返回值类型会报错

C同理 static修饰的方法也不允许重写

D 解释一下D,private是本类可见,但本类可修改,加上final就是仅本类可见且不可修改的方法。

E private修饰的方法仅本类可见,而abstract需要子类去重写该方法,子类不可见就无法完成重写。故而矛盾

Q8

1.代码改错: interface IA{

void m1();

int a = 100;

}

class MyClass implements IA{

void m1(){}

}

public class TestInterface{

public static void main(String args[]){
IA ia = new MyClass();
ia.m1();
System.out.println(IA.a);

}

}

答案:需要在MyClass类中将方法前面加public,实现接口中的抽象方法时,修饰符必须为public

2.代码填空: interface IA{

void m1();
void m2();

}

_____ class MyClassA implements IA{

public void m1(){}

}

class MyClassB extends MyClassA{

_______________ {}

}

答案:第一个空填abstract,第二个填public void m2(){}

因为第一个类中没有完全覆盖引用接口中的方法,所以是个抽象类,需要加abstract修饰符,第二个类没有abstract修饰符,证明将接口方法完全覆盖了,故而将MyClass没有覆盖的方法进行覆盖。

发布了7 篇原创文章 · 获赞 1 · 访问量 139

猜你喜欢

转载自blog.csdn.net/llpiong/article/details/104506621