OOP(面向对象)
1:说出一些常用的类,包,接口,请各举5个
常用的类:BufferedReader BufferedWriter FileReader FileWirter String Integer
常用的包:java.lang java.awt java.io java.util java.sql
常用的接口:Remote List Map Runnable Serializable ActionListener
2: 什么是类与对象?
所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念。
类是具备某些共同特征的实体的集合,它是一种抽象的概念,用程序设计的语言来说,类是一种抽象的数据类型,它是对所具有相同特征实体的抽象。
3: 属性与方法?
不同对象具有相同特点,就可能抽象为一定的类,那么这些特点基本上可以分为两类,一类是描述对象静态状态的,就是对象的属性,在程序设计中,可以称之为变量;另一类是描述对象的动作,就是对象的方法,在程序设计中我们称之为函数。属性和方法是一个对象所具备的两大基本要素,也是我们后面编程工作的核心。
3: 什么是封装?
只要有足够的方法,就没必要直接去操作对象属性,只要调用这些方法就可以实现要完成的任务,这种现象称为封装,它通过对象方法对其属性的操作把对象属性封装在一个对象内部,对象与外界打交道全部通过其自身的方法来实现,有效的把对象属性隐藏在对象内部。
4. 什么是OOP?什么是类?请对比类和对象实例之间的关系。
OOP是Object_oriented Programming(面向对象编程)的缩写。这主要是为了区别于以前的面向过程的程序设计!指的是用对象的观点来组织与构建系统,它综合了功能抽象和数据抽象,这样可以减少数据之间的耦合性和代码的出错几率。使用面向对象编程技术可以使得软件开发者按照现实世界里人们思考问题的模式编写代码,可以让软件开发者更好地利用代码直接表达现实中存在的对象,将问题空间直接映射到解空间!类:即class 在面向对象的程序设计中,专门用“类”来表示用户定义的抽象数据类型(user_defined abstract type)。它将具有相同状态、操作和访问机制的多个对象进行了抽象。类具有继承、数据隐藏和多态三种主要特性。利用类的这三种特性可以更好地表示现实世界中事物。类是同一类对象实例的共性的抽象,对象是类的实例化。对象通常作为计算机模拟思维,表示真实世界的抽象,一个对象就像一个软件模块,可以为用户提供一系列的服务---可以改变对象的状态、测试、传递消息等。类定义了对象的实现细节或数据结构。类是静态的,对象是动态的,对象可以看作是运行中的类。类负责产生对象,可以将类当成生产对象的工厂(Object factory).
5:abstract class和interface的区别?
抽象类:包含一个抽象方法的类就是抽象类,抽象类要使用abstract关键字声明,抽象类必须有子类,而且通过对象多态性可以直接为父类对象进行实例化,一个抽象类可以包含任意的东西,包括构造方法、普通方法、抽象方法、属性、全局常量等等,可以包含内部接口或抽象类,模板设计
接口:由抽象方法和全局常量组成的特殊类称为接口,接口可以被实现,一个类可以同时实现多个接口,但是一个接口只允许继承其他接口,通过接口可以实现多继承的关系,一个接口中可以包含其他的内部接口或内部类。代理、工厂。
6: Java中多态的机制? 父类引用指向子类对象。
7: 面向对象程序设计方法:
1):所有东西都是对象,可从要解决的问题上提出所有概念性的组件,然后在程序中将其表达为一个对象。
2):程序是一大堆对象的组合;通过消息传递,各对象知道自己该做什么,可将消息想象为一个调用请求,它调用的是
从属于目标对象的一个子例程或函数。
3):每个对象都有自己的存储空间,可容纳其它对象。通过封装现有对象,可制作出新型对象。
4):每个对象都有一种类型class.一个类最重要的特征就是“能将什么消息发给它”。
5):同一类所有对象都能接受相同的消息。
8: 所有对象——尽管各有特色——都属于某一系列对象的一部分,这些对象具有通用的特征和行为。
“类型” 决定了接口,而“类”是那个接口的一种特殊实现方式。建好一个类后,可根据情况生成许多对象。每个对象仅能接受特定的请求。我们向对象发出的请求是通过它的“接口”定义的,对象的“类型”或“类”则规定了他的接口形式。类型与接口的等价或对应关系是面向对象程序设计的基础。
“接口”interface规定了可对一个特定的对象发出哪些请求。为重复使用一个类,最简单的办法是仅直接使用哪个类的对象。但同时也能将那个类的一个对象植入一个新的类。
组织——在现有类的基础上组织一个新类。也称作“包含”关系。新类的“成员对象”通常设为”私有“Private,这样可在不干扰客户代码的前提下,从容的修改那些成员。
继承:重新使用接口
在继承过程中,若原始类发生了改变,修改过的子类也会反映出这种变化,继承是通过extends关键字实现的。
使用继承时,相当于创建了一个新类,它不仅包含了现有类型的所有成员,更重要的是,他复制了基础类的接口。
有两种做法可将新得到的衍生类与原来的基础类区分开。1.为衍生类添加新函数(功能)。2.改变基础类一个现有函数的行为。
基础类只为自己的衍生类提供一个接口,我们不想其他任何人实际创建基础类的一个对象,就需要把那个类变成”抽象“abstract
9: opp面向对象程序设计:涉及抽象的数据类型、继承及多形性。对象的创建时间和存在时间:若再堆栈或在静态存储空间里创建对象,编译器会判断对象的持续时间有多长,到时会自动”破坏“或清除。可用两种方法破坏一个对象:用程序化的方式决定何时破坏对象,或者另用由运行环境提供的一种”垃圾收集器“特性,自动寻找那些不再使用的对象,将其清除。
单根结构:所有对象都有一个通用接口,所以他们最终都属于相同的类型。单根结构中的所有对象都可以保证拥有一些特定的功能,在自己的系统中,对每个对象都能进行一些基本操作。一个单根结构,加上所有对象都在内存堆中创建,可极大简化参数的传递。
10: 编程因注意的问题:1.对象是什么? 2.他们的接口是什么?
分析和设计
阶段0:决定在后面的过程中采取哪些步骤。
阶段1:建立需求分析和系统规格,需求分析,就是你和客户之间的一份合约。系统规格,是对所面临的问题的最高级别的一种揭示,我们依据它判断任务是否完成,以及需要花多长的时间。
阶段2:如何构建,拿出一套设计方案,并解释其中包含的各类对象在外观上是什么样子,以及相互间是如何沟通的
阶段3:开始创建,
阶段4:校订,整个
11、java中实现多态的机制是什么?
答:方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。
12、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。
OverLoad:在一个类中出现的,方法名称相同,参数的类型或个数不同,没有权限要求
Override:在继承类中出现的,方法名称,参数的类型或个数相同,注意访问权限不能更加严格
OverLoad只是根据参数的类型或个数来确定的,与返回值类型无关。
13、抽象类与接口?
答:抽象类与接口都用于抽象,但是抽象类(JAVA中)可以有自己的部分实现,而接口则完全是一个标识(同时有多重继承的功能)。
JAVA类实现序例化的方法是实现java.io.Serializable接口
Collection框架中实现比较要实现Comparable 接口和 Comparator 接口
抽象类与接口都用于抽象,但是抽象类(JAVA中)可以有自己的部分实现,而接口则完全是一个标识(同时有多重继承的功能)。
14、abstract class和interface有什么区别?
声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。
抽象类和接口的区别
1:一个类可以实现任意多的接口,但是最多只能对一个抽象类进行子类化。
2:一个抽象类可以包括非抽象方法,而一个接口的所有方法在效果上都是抽象的。
3:一个抽象类可以申明并使用变量,而一个接口不行。
4:一个抽象类中的方法的访问修饰符可以使public,internal,protected,protected internal,private,而接口成员的访问修饰符在默认情况下都是public,而且,在申明接口成员时,不允许使用访问修饰符(甚至不能使用public)。
5:一个抽象类可以定义构造函数,而一个接口不行。
15、Static Nested Class 和 Inner Class的不同。
Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。
答:Nested Class (一般是C++的说法),Inner Class (一般是JAVA的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。注: 静态内部类(Inner Class)意味着1创建一个static内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象
16、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
可以继承其他类或完成其他接口,在swing编程中常用此方式。
答:匿名的内部类是没有名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现
17、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。
18、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
都不能
19、构造器Constructor是否可被override?
构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。
20、java中实现多态的机制是什么?
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。
21、内部类可以引用他包含类的成员吗?有没有什么限制?
一个内部类对象可以访问创建它的外部类对象的内容
22 .Core Java:
子类重写父类方法的时候,方法返回值的类型一定相同,否则编译不通过
如果子类实现多态时,若只是方法的返回值不同,将在第二个及以后的方法编译出错
如果实现多态时,方法的参数是f(int ,int)和f(long , int);那么f(1,2)将执行f(int , int)
初始化顺序:
1>
Class Initialization, super?sub(static block and static variable)
2>
Creation of new class instances,
3>
JVM allocation memory?
4>
init variable default value ?
5>
call constructor(super?sub)?
6>
init variable(set the value to the variable)?
7>
execute other code in constructor.
public class InitializationOrder {
public static void main(String[] args) {
Subclass sb = new Subclass();
}
}
class Super{
static {
System.out.println(1);
}
Super(int i){
System.out.println(i);
}
}
class Subclass extends Super implements Interface{
static {
System.out.println(2);
}
Super su = new Super(4);
Subclass() {
super(3);
new Super(5);
}
}
interface Interface{
static Super su = new Super(0);
}
23 .以下程序的输出结果为?( B. “AB,B” )
Public class Foo {
Public static void main (String [] args){
StringBuffer a = new StringBuffer(“A”);
StringBuffer b = new StringBuffer(“B”);
operate(a,b);
System.out.println(a+”,”+b);
}
static void operate (StringBuffer x,StringBuffer y) {
x.append(y);
y = x;
}
}
24.
以下那些描述是正确的 ( B )
A. Static 变量和方法旨在类中实例化一次
B. System.out.println(“11”+5);输出结果为115
C. 可以在ClassA.java文件中定义一个公用类ClassB
D. main是java的关键字
E. 第一个catch 语句获取到exception 后,后续的catch 语句将忽略该exception 并不再作处理
25.请之处下段代码错误的地方:
Abstract class Name { // 首字母小写
Private String name; // 首字母小写
Public abstract boolean isAGoodName(String name) {}
// 第一种: 不能使用 abstract ,必须有返回值 即 public boolean isAGoodName(String name){ return false; }
// 第二种 或者去掉{} 即: public abstract boolean isAGoodName(String name);
}
26 :请指出下段代码错误的地方:
// 不能在静态方法直接调用非静态的方法,可以使用 s.doSomething()
Public class Something {
Public static void main(String[] args){
Something s = new Something();
System.out.println(“s.doSomething() return s”+doSomething()); }
Public String doSomething(){
return “Do something ……”; }}
27 :两个对象同属于一个类,它们的值相同(x.equals(y) == true),但却可有不同的hash Code,这句话对不对
不对,有相同的hash code。
28: 改错
public class A {
private int a;
public int change(int m) {
return m;
}
}
public class B extends A {
public int b;
public static void main(String args[] ) {
A aa = new A();
B bb = new B();
int k;// px}
k= m; // // 不正确
k=aa.a; // 不正确 a 是私有的
k=bb.change(30);
k=bb.a; // 不正确 a 是私有的
}
}
29:
class A{
public A() {
a1();
}
public void a1() // 在方法被a1()被重写的情况下,父类的a1是没有机会被调用的.
{
System.out.println("A-a1");
}
}
public class B extends A{
int bb = 0;
public B()
{
bb = 1000;
}
public void a1() // 父类中的方法被 重写
{
System.out.println("bb is " + bb);
System.out.println("B-a1");
}
public static void main(String[] args)
{
new B(); // 首先是父类中构造方法初始化,调用子类中的a1()
}
}
//
答案:
//
bb is 0
//
B-a1
// 下面是 程序的执行顺序
package com;
class A{
//3
public A(){
a1();
}
public void a1() {
System.out.println("A-a1");
}
}
public class B extends A{
int bb = 0;
//2
public B(){
//5
bb = 1000;
}
//4
public void a1(){
System.out.println("bb is " + bb);
System.out.println("B-a1");
}
public static void main(String[] args){
//1
new B(); }
}
在方法被a1()被重写的情况下,父类的a1是没有机会被调用的.
30:: class A{
public int a;
public int change(int m){
return m;
}
public A(){
System.out.println("constructA");
a1();
}
public void a1(){
System.out.println("A - a1");
}
}
public class B extends A{
int bb = 0;
public B(){
System.out.println("constructB");
bb = 1000;
System.out.println("bb = " + bb);
}
public void a1(){
System.out.println("bb is " + bb);
System.out.println("B - a1");
}
public static void main(String[] args){
new B();
}
}
//执行结果:
//constructA
//bb is 0
//B - a1
//constructB
//bb = 1000
31:
public class Test {
public static void changeStr(String str) {
str = "welcome";
}
public static void main(String[] args) {
String str = "1234";
changeStr(str);
System.out.println(str);
}
}
// 此题结果为:1234;
32: public class ForTest {
static boolean foo(char c) {
System.out.println(c);
return true;
}
public static void main(String[] args){
//
foo('A'); // 总为true
//
foo('B');
int i = 0;
for (foo('A'); foo('B') && (i < 2); foo('C'))
{
i++;
foo('D');
}
}
}
// }此题结果为:ABDCBDCB
// 这道题考查的for循环的执行顺序.
// for(int i = 0; i < 10; i ++) {}
// 首先先执行int i = 0;注意这个只是初始化一次,
// 就是在第一次的时候.接着执行i < 10;
// 然后执行方法体{}里面的内容,最后才执行i++;
// 第二次及以后就直接执行i <10;然后方法体;最后
// i ++;如此顺序直到结束为止.
33:
class A {
protected int method1(int a, int b) {
return 0;
}
}
public class ForTest extends A{
// Which two are valid in a class that extends class A? (Choose two)
}
// A. public int method1(int a, int b) { return 0; }
// B. private int method1(int a, int b) { return 0; }
// C. private int method1(int a, long b) { return 0; }
// D. public short method1(int a, int b) { return 0; }
// E. static protected int method1(int a, int b) { return 0; }
// 此题考查的是继承重写问题.
// 当一个子类重写父类的方法时,重写的方法的访问权限
// 必须大于等于父类的访问权限.
// 在此题中父类中的方法访问权限为protected,子类只能是
// protected或public.这时A是符合题意的.
// 由于选项C的形参和父类的不一样,没有重写的效果,所以
// 在子类出现也是没问题的.
// 所以此题选:AC
34: 内部类:
public class Outer { // 外部类
public void someOuterMethod() {
// Line 3
//
new Inner(); // 正确的
}
public class Inner {} // 内部类
public static void main(String[] argv) {
Outer o = new Outer();
// Line 8
new Inner(); // 不正确
}
}
//内部类的实例化可以在普通方法里也可以在static方法里实例化.
// Which instantiates an instance of Inner?
// A. new Inner(); // At line 3
// B. new Inner(); // At line 8
// C. new o.Inner(); // At line 8
// D. new Outer.Inner(); // At line 8//new Outer().new Inner()
// 此题选A.
35: 内部类:
public class Outer { // 外部类
Inner i = new Outer.Inner(); // 内部类的对象,可以使用外部类的对象来创建
public void method() {
new Inner(); // 内部类的实例
}
public class Inner {}
public static void main(String[] args) {
Outer o = new Outer();
Inner i = o.new Inner(); // 在静态方法中创建内部类的实例
}
static void a() {
Outer o = new Outer();
Inner i = o.new Inner(); // 在静态方法中创建内部类的实例
}
}
36: 构造方法:
public class Jtest {
int m = 1;
int i = 3;
void Jtest() { // 一般方法
m = 2;
i = 4;
}
public static void main(String[] args) {
Jtest app = new Jtest();
System.out.println(app.m + "," + app.i);
}
}
// 写出输出.
// 结果是1,3;
// 因为在这里void Jtest();并没有并调用,它只是一个
// 方法,而非构造方法,这样的编写是有警告的,不过可以运行.
37: 无参的构造方法:
public class Jtest {
int m = 1;
int i = 3;
Jtest() {
m = 2;
i = 4;
}
public static void main(String[] args) {
Jtest app = new Jtest();
System.out.println(app.m + "," + app.i);
}
}
// 写出输出:
// 结果是2,4;
// 调用了构造方法,不加修饰符,默认访问权限是
// package access,在Java里没有关键字表示,就是
// 包内的能访问,包外就不行了(即使导入也不行).
38: 打印结果:
public class Test {
static void oper(int b) {
b = b + 100;
}
static void oper(String str) {
str = str+ 100;
}
public static void main(String[] args) {
int a = 99;
oper(a);
System.out.println(a);
String s = "xxxg";
oper(s);
System.out.println(s);
}
}
// 输出为: 99
// xxxg
// 我们来分析一下内存:
// int a = 99;
// 首先在栈里面开辟一块空间保存a
// 比如:a:xxxx
// 然后调用oper(a);
// 这时把a 的值99赋给int b;
// b在内存里也开辟了自己的空间,此时
// 值也是99.
// 然后执行oper(a);方法体,b = b + 100;
// 此时b的值为199,a的值为99.
39: 字符串:
public class Test {
public static void main(String[] args) {
String a = new String("A");
String b = new String("B");
oper(a, b);
System.out.print(a + "," + b);
}
static void oper(String c, String d) {
c.concat("B");
d = c;
}
}
// 此程序输出:A,B.
// 原因就是String是final类型的.并不会被改变.
40: public class Test{
public static void main(String[] args)
{
String a = new String("A");
String b = new String("B");
a.concat("aa");
System.out.println(a + "," + b);
}
}
//这个还是会输出A,B
//原因同上.
41:
public class Test {
public static void main(String[] args) {
String a = new String("A");
String b = new String("B");
a = a.concat("aa");
System.out.println(a + "," + b);
}
}
// 做了下改动,再来看看.结果就不同了.
// 输出的是Aaa,B
// 因为String 是final类型的.所以执行到
// a = c.concat("aa");
// 会在heap里新创建一个对象,而a指向它.
// 这是一新的地址,同String a 这个已经不同了.
// 所以输出的是后一个.即改变后的值.
42:
public class Test {
static void oper(StringBuffer c, StringBuffer d) {
d = c.append("B"); // AB
}
public static void main(String[] args) {
StringBuffer a = new StringBuffer("A");
StringBuffer b = new StringBuffer("B");
oper(a, b);
System.out.println(a + "," + b);
}
}
// 此程序会输出:AB,B
43: 多态:
public class Test {
public static void main(String[] args) {
A a = new B();
a.print(); // 因为父类中的方法被重写,所以条用子类中的方法
}
}
class A {
private int i = 1;
public A() {
int i = 2;
}
public void print() {
System.out.println("A---》The result is:" + i);
}
}
class B extends A {
private int i = 3;
public B() {
int i = 6;
}
public void print() {
System.out.println("B---》The result is:" + i);
}
}
// 输出结果是:B---》The result is:3
// 此题考查的是多态.
// 在这里是父类的引用指向子类的对象.
// 父类的引用只能访问子类和父类共有的方法.
//这个程序我通过Eclipse和Debug程序观察它的
//执行顺序是这样的:
public class Test {
public static void main(String[] args) {
A a = new B();
a.print();
}
}
class A {
// 3
private int i = 1;
// 2
public A() {
// 4
int i = 2;
}
public void print() {
System.out.println("The result is:" + i);
}
}
class B extends A{
// 5
private int i = 3;
// 1
public B()
{
// 6
int i = 6;
}
public void print()
{
System.out.println("The result is:" + i);
}
}
44: //现在将程序稍微改动一下:
public class Test {
public static void main(String[] args) {
A a = new B();
a.print();
}
}
class A {
// 3
private int i = 1;
// 2
public A() {
// 4
int i = 2;
}
public void print() {
System.out.println("The result is:" + i);
}
}
class B extends A { // 5
private int i = 3; // 1
public B() { // 6
int i = 6;
}
public void print2() {
System.out.println("The result is:" + i);
}
}
打印结果是: The result is:1
45: // 继承时候类的执行顺序问题,一般都是选择题,问你将会打印出什么?
class FatherClass {
public FatherClass() {
System.out.println("FatherClass Create");
}
}
public class ChildClass extends FatherClass {
public ChildClass() {
System.out.println("ChildClass Create");
}
public static void main(String[] args) {
FatherClass fc = new FatherClass();
ChildClass cc = new ChildClass();
}
}
// 输出结果:
// FatherClass Create
// FatherClass Create
// ChildClass Create
46: // 内部类的实现方式?
public class OuterClass {
private class InterClass { // 定义一个內部类
public InterClass() { // 内部类的构造方法
System.out.println("InterClass Create");
}
}
public OuterClass() {
InterClass ic = new InterClass();
System.out.println("OuterClass Create");
}
public static void main(String[] args) {
OuterClass oc = new OuterClass();
}
}
// 输出结果:
// InterClass Create
// OuterClass Create
47: 静态内部类
public class OuterClass {
private double d1 = 1.0;
// insert code here
}
// You need to insert an inner class declaration at line 3.
// Which two inner class declarations are valid?(Choose two.)
// A. class InnerOne{
// public static double methoda() {return d1;}
// }
// B. public class InnerOne{
// static double methoda() {return d1;}
// }
// C. private class InnerOne{
// double methoda() {return d1;}
// }
// D. static class InnerOne{
// protected double methoda() {return d1;}
// }
// E. abstract class InnerOne{
// public abstract double methoda();
// }
// 说明如下:
// 一.静态内部类可以有静态成员,而非静态内部类则不能有静态成员。 故 A、B 错
// 二.静态内部类的非静态成员可以访问外部类的静态变量,而不可访问外部类的非静态变量;return d1 出错。
// 故 D 错
// 三.非静态内部类的非静态成员可以访问外部类的非静态变量。 故 C 正确
// 四.答案为C、E
48: 指出错误:
abstract class Name {
private String name;
public abstract boolean isStupidName(String name) {}
}
答案: 错。abstract method必须以分号结尾,且不带花括号。
49: 指出错误:
public class Something {
void doSomething () {
private String s = "";
int l = s.length();
}
}
有错吗?
答案: 错。局部变量前不能放置任何访问修饰符 (private,public,和protected)。final可以用来修饰局部变量
(final如同abstract和strictfp,都是非访问修饰符,strictfp只能修饰class和method而非variable)。
50: 指出错误:
abstract class Something {
private abstract String doSomething ();
}
这好像没什么错吧?
答案: 错。abstract的methods不能以private修饰。abstract的methods就是让子类implement(实现)具体细节的,怎么可以用private把abstract
method封锁起来呢? (同理,abstract method前不能加final)。
51: 指出错误:
public class Something {
public int addOne(final int x) {
return ++x;
}
}
这个比较明显。
答案: 错。int x被修饰成final,意味着x不能在addOne method中被修改。
52: 指出错误:
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++;
System.out.print(o.i++); //输出 结果:1
}
}
class Other {
public int i;
}
// 和上面的很相似,都是关于final的问题,这有错吗?
// 答案: 正确。在addOne method中,参数o被修饰成final。如果在addOne method里我们修改了o的reference
// (比如: o = new Other();),那么如同上例这题也是错的。但这里修改的是o的member vairable
// (成员变量),而o的reference并没有改变。
53: 指出错误:
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。
54: 指出错误:
class Something {
final int i; 这个错误
// final int i = 123; 这个正确
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;"。
55: 指出错误:
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。
56: 此处,Something类的文件名叫OtherThing.java
class Something {
private static void main(String[] something_to_do) {
System.out.println("Do something ...");
}
}
这个好像很明显。
答案: 正确。从来没有人说过Java的Class名字必须和其文件名相同。但public class的名字必须和文件名相同。
57: 指出错误:
interface A{
int x = 0;
}
class B{
int x =1;
}
class C extends B implements A {
public void pX(){
System.out.println(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来明确。
58: 指出错误:
interface Playable {
void play();
}
interface Bounceable {
void play();
}
interface Rollable extends Playable, Bounceable {
Ball ball = new Ball("PingPang");
}
class Ball implements Rollable {
private String name;
public String getName() {
return name;
}
public Ball(String name) {
this.name = name;
}
public void play() {
ball = new Ball("Football"); // 在接口中声明是final类型的,不可变的,所有错误
System.out.println(ball.getName());
}
}
//这个错误不容易发现。
//答案: 错。"interface Rollable extends Playable, Bounceable"没有问题。
//interface可继承多个interfaces,所以这里没错。
//问题出在interface Rollable里的"Ball ball = new Ball("PingPang");"。
//任何在interface里声明的interface variable (接口变量,也可称成员变量),
//默认为public static final。也就是说"Ball ball = new Ball("PingPang");"
//实际上是"public static final Ball ball = new Ball("PingPang");"。
//在Ball类的Play()方法中,"ball = new Ball("Football");"改变了ball的reference,
//而这里的ball来自Rollable interface,Rollable interface里的ball是public static final的,
//final的object是不能被改变reference的。因此编译器将在"ball = new Ball("Football");"
//这里显示有错。