阶段考核
1:
下面关于接口的说法中不正确的是()
A.接口中所有的方法都是抽象的
B.接口中所有的方法都是public访问权限
C.子接口继承父接口所用的关键字是implements
D.接口是Java中的特殊类,包含常量和抽象方法
2:
Java语言接口间的继承关系是()。
A.单继承
B.多重继承
C.不能继承
D.不一定
3)一个类实现接口的情况是()。
A.一次可以实现多个接口
B.一次只能实现一个接口
C.不能实现接口
D.不一定
填空题:
1)_____是声明接口的关键字,可以把它看成一个特殊类。接口中的数据成员默认的修饰符是_____,接口中的成员方法默认的修饰符是_____。
2)如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须该接口的所有抽象方法;如果实现某接口的类是abstract的抽象类,则它可以该接口所有的方法。但是对于这个抽象类任何一个非抽象的子类而言,它们父类所实现的接口中的所有抽象方法以及自身所实现接口中的抽象方法都必须有实在的。
implements public final , public abstract
abstract class 和interface 有什么区别?
答:声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。
不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。
Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法 接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。
接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。
然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换
,instanceof 运算符可以用来决定某对象的类是否实现了接口
接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
答案是: 接口可以继承接口。抽象类可以实现(implements)接口, 抽象类可继承实体类,但实体类必须不能是如下两种情况之一: 1,final修饰符修饰的类是不能的 2,如果此实体类有且仅有私有的构造函数也是不能的。
是否能通过编译?
interface A{
int x = 0;
}
class B{
int x =1;
}
class C extends B implements A {
public void pX(){
System.out.println(x); //super.x A.x
}
public static void main(String[] args) {
new C().pX();
}
}
答案:错误。在编译时会发生错误(错误描述不同的JVM有不同的信息,意思就是未明确的x调用, 两个x都匹配(就象在同时import java.util和java.sql两个包时直接声明Date一样)。对于父类的变量,可以用super.x来明确, 而接口的属性默认隐含为 public static final.所以可以通过A.x来明确。
写出程序结果
interface A{}
class B implements A{
public String func(){
return "func";
}
}
class Demo{
public static void main(String[] args){
A a=new B();
System.out.println(a.func());
}
}
编译失败:因为A接口中并未定义func方法。
编一个程序,包含以下文件
(1)Shape.java文件,在该文件中定义接口类Shape,该接口在shape包中。 属性:PI。 接口:求面积的方法area()。 (2)Circle.java文件,在该文件中定义圆类Circle,该类在circle包中,实现Shape接口类。 属性:圆半径radius。 方法:构造器;实现求面积方法area();求周长方法perimeter()。 (3)Cylinder.java文件,在该文件中定义圆柱体类Cylinder,该类在cylinder包中,继承圆类。 属性:圆柱体高度height。 方法:构造器;求表面积方法area();求体积方法volume()。 (4)X5_3_6.java文件,在该文件中定义主类X5_3_6,该类在默认包中,其中包含主方法main(),
在主方法中创建两个圆类对象cir1和cir2,具体尺寸自己确定,并显示圆的面积和周长;再创建两个圆柱体类的对象cy1和cy2,
具体尺寸自己确定,然后分别显示圆柱体cy1和cy2的底圆的面积和周长以及它们各自的体积和表面积。 【编程分析】本题主要考察接口、包、继承、封装等问题。
按要求实现下列问题:
1) 动物类Animal包含了抽象方法 abstract void shout();
2) Cat类继承了Animal,并实现方法shout,打印“猫会喵喵叫”
3) Dog类继承了Animal,并实现方法shout,打印“狗会汪汪叫”
4) 在测试类中实例化对象Animal a1 =new Cat(),并调用a1的shout方法
5) 在测试类中实例化对象Animal a2 =new Dog(),并调用a2的shout方法
public class MayShape { public static void main(String[] args) { MayAnimal a1 = new MayCat(); MayAnimal a2 = new MayTwentyDog(); a1.shout(); a2.shout(); } } abstract class MayAnimal{ public abstract void shout(); } class MayCat extends MayAnimal{ @Override public void shout() { System.out.println("cat can shout"); } } class MayTwentyDog extends MayAnimal{ @Override public void shout(){ System.out.println("Dog can shout"); } }
interface A{ int x = 0; } class B{ int x = 1; } class C extends B implements A{ public void printX(){ System.out.println(x); } public static void main(String[] args) { new C().printX(); } } 答案:编译错误 System.out.println(x);报错,x有歧义
class TD { int y = 6; class Inner { static int y = 3; void show() { System.out.println(y); } } } class TC { public static void main(String[] args) { TD.Inner ti = new TD().new Inner(); ti.show(); } } 编译失败,非静态内部类中不可以定义静态成员。 内部类中如果定义了静态成员,该内部类必须被静态修饰。
判断题 1)内部类(可以/不可以)了解外部类 2)静态内部类用修饰。 3)外部类(可以/不可以)通过类名访问静态内部类里的静态成员(变量和方法) 4)外部类(可以/不可以)通过类名访问非静态内部类里的成员(变量和方法) 5)非静态内部类可以访问外部类的成员,也能访问外部类的成员 6)静态内部类可以访问外部类的成员,不能访问外部类的成员 7)非静态内部类(可以/不可以)用static修饰她的成员(变量和方法)
抽象类与抽象方法 abstract 的method 是否可同时是static,是否可同时是native,是否可同时是synchronized? 答:都不能 因为抽象方法是需要被实现的
抽象类和抽象方法之间的关系 定义抽象类和抽象方法的关键字是(abstract)。抽象类中(可以)(可以/不可以)有抽象方法,
(可以)(可以/不可以)有普通方法(可以)(可以/不可以)有属性;一个类中定义了抽象方法,
那这个类(必须)(必须/不必须)用abstract修饰,即抽象类。
判断题 abstract class Name { private String name; public abstract boolean isStupidName(String name) {} } 这有何错误? 答案: 错。abstract method必须以分号结尾,且不带花括号。
是否可以通过编译? abstract class Something { private abstract String doSomething (); } 答案: 错。abstract的methods不能以private修饰。 abstract的methods就是让子类implement(实现)具体细节的, 怎么可以用private把abstract method封锁起来呢? (同理,abstract method前不能加final)。
Static
是否可以从一个static方法内部发出对非static方法的调用?
答:不可以,如果其中包含对象的method();不能保证对象初始化.
写一个单例模式
饿汉式 class MayTwentyOnlyOne{ private MayTwentyOnlyOne(){} private static MayTwentyOnlyOne onlyOne = new MayTwentyOnlyOne(); public static MayTwentyOnlyOne getOnlyOne(){ return onlyOne; } } 懒汉式 class MayTwentyOnlyTwo{ private MayTwentyOnlyTwo(){} private static MayTwentyOnlyTwo onlyTwo = null; public static MayTwentyOnlyTwo getOnlyTwo(){ if(onlyTwo == null){ onlyTwo = new MayTwentyOnlyTwo(); } return onlyTwo; } }
public class Something { public static void main(String[] args) { Something s = new Something(); System.out.println("s.doSomething() returns " + doSomething()); } public String doSomething() { return "Do something ..."; } } 看上去很完美。 答案: 错。看上去在main里call doSomething没有什么问题,毕竟两个methods都在同一个class里。 但仔细看,main是static的。static method不能直接call non-static methods。 可改成"System.out.println("s.doSomething() returns " + s.doSomething());"。 同理,static method不能访问non-static instant variable。
写出程序结果
public class Demo { private static int j = 0; private static boolean methodB(int k) { j += k; return true; } public static void methodA(int i) { boolean b; b = i < 10 | methodB(4); b = i < 10 || methodB(8); } public static void main(String args[]) { methodA(0); System.out.println(j); } }
| 按位或 先判断 条件1 不管条件1 是否式true 都会执行条件2
|| 逻辑或 先判断条件1 如果条件1 为true就不执行条件2
final关键字
谈谈final, finally, finalize的区别(后面异常中讲finally) 答:final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为
abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,
而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载
finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,
那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话) finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。
子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的
如下程序是否可通过编译? public class Something { public int addOne(final int x) { return ++x; } } 这个比较明显。 答案: 错。int x被修饰成final,意味着x不能在addOne method中被修改。
如下程序是否可通过编译?
public class Something { public static void main(String[] args) { Other o = new Other(); new Something().addOne(o); } public void addOne(final Other o) { o.i++; } } class Other { public int i; } 和上面的很相似,都是关于final的问题,这有错吗? 答案: 正确。在addOne method中,参数o被修饰成final。如果在addOne method里我们修改了o的reference (比如: o = new Other();),那么如同上例这题也是错的。但这里修改的是o的member vairable (成员变量),而o的reference并没有改变
如下程序是否可通过编译?
class Something { int i; public void doSomething() { System.out.println("i = " + i); } } 答案: 正确。输出的是"i = 0"。int i属於instant variable (实例变量,或叫成员变量)。instant variable有default value。 int的default value是0。
接上题 class Something { final int i; public void doSomething() { System.out.println("i = " + i); } } 和上面一题只有一个地方不同,就是多了一个final。这难道就错了吗? 答案: 错。final int i是个final的instant variable (实例变量,或叫成员变量)。final的instant variable没有default value,
必须在constructor (构造器)结束之前被赋予一个明确的值。可以修改为"final int i = 0;"。
以下代码的运行结果是?
public class Test { static int x, y, z; static { int x = 5; x--; } static { x--; } public static void main(String[] args) { System.out.println("x=" + x); z--; method(); System.out.println("result:" + (z + y + ++z)); } public static void method() { y = z++ + ++z; } }
答案:
x=-1
result:3