JAVA核心技术I---JAVA基础知识(知识回顾)
一:多态问题
class Father { public void hello() { System.out.println("Father says hello."); } } public class Child extends Father { int age=10; static int number=20; public void hello() { System.out.println("Child says hello"); } public static void main(String[] a) { Child foo = new Child(); //foo.hello(); Father foo2 = (Father) foo; //Father foo2 = foo;是可以的,父类指针指向子类对象 //foo2.hello(); Child foo3 = (Child) foo2; //Child foo3 = foo2;直接转换是不能编译通过的,只有使用强制转换(前提foo2本来就是子类转换来的) //foo3.hello(); System.out.println(foo==foo2); System.out.println(foo==foo3); } }
true true
无论父类指针还是子类指针,指向的都是该内存区域的起始地址。对于函数调用。可以认为同C++中虚函数表一样去寻找函数入口地址解析执行
二:初值问题,以及null类型输出null
下面代码的运行结果为:() public class Foo { static String s; public static void main (String[]args) { System.out.println ("s=" + s); } }
A.代码得到编译,并输出“s=” B.代码得到编译,并输出“s=null” C.由于String s没有初始化,代码不能编译通过 D.代码得到编译,但捕获到 NullPointException异常
String类型数据默认null,空。但是输出时可以输出null。
Java String是如何输出NULL的
主要在于print方法的实现,println方法是print和newline方法一起达到目的的,看源码可以发现
print方法内部,当判断为空时,则赋值一个null字符串给变量,然后输出
对于申明的变量是一个非String类型的Object时,打印还是null
其原因还是print方法的另一个不同类型参数的重载实现,其内部会将该对应的转换成字符串,然后print方法内部,当判断为空时,则赋值一个null字符串给变量,然后输出
对于不同类型的其他变量,打印输出也大致是这个思路,然后打印出null
public void print(String s) { write(String.valueOf(s)); }
public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); }
三:main主函数
java中的main方法必须有一个外壳类。
当一个类中有main()方法,执行命令“java 类名”则会启动虚拟机执行该类中的main方法。
由于JVM在运行这个Java应用程序的时候,首先会调用main方法,调用时不实例化这个类的对象,而是通过类名直接调用因此需要是限制为public static。
由于main入口函数与外壳类的关系只是借用,且不需要实例化该类,所以,可以在抽象类中实现该main函数
Given: abstract class Bar { public int getNum() { return 38; } } public abstract class AbstractTest { public int getNum() { return 45; } public static void main(String[] args) { AbstractTest t = new AbstractTest() { public int getNum() { return 22; } }; Bar f = new Bar() { public int getNum() { return 57; } }; System.out.println(f.getNum() + " " + t.getNum()); } } What is the result?
A.57 22 B.45 38 C.45 57 D.An exception occurs
四:类嵌套(父类/子类成员变量相同时的调用)《重点》
现有: class Tree { private static String tree = "tree"; String getTree() { return tree; } } public class Elm extends Tree { private static String tree = "elm"; public static void main(String[] args) { new Elm().go(new Tree()); } void go(Tree t) { String s = t.getTree() + Elm.tree + tree + (new Elm().getTree()); System.out.println(s); } }
A.elmelmelmelm
B.treeelmelmelm
C.treeelmelmtree
D.treeelmtreeelm
注意:(同C++一样)
只有方法重写覆盖,没有成员变量覆盖,当子类和父类出现一样的成员变量名时,会在内存中出现两个不同内存分别存放。
至于最后取谁的数据,取决于调用的该成员变量的方法是属于子类还是父类的!!,也取决于指针是父类指针还是子类指针
五:父类/子类成员变量相同时的调用-->取决于指针是父类还是子类
请问以下代码的输出是什么: class A { public static int x = 10; public static void printX() { System.out.print(x); } } public class Elm extends A { public int x = 20; public static void main(String[] args) { A a = new Elm(); //父类指针,自然是指向父类变量x printX(); System.out.print("和"); System.out.print(a.x); //这个方法 } }
A.10和20
B.20和10
C.10和10
D.20和20
补充:普通成员变量和方法重写《重点》
class Father{ public String name="ld"; public void say() { System.out.println(name+" father"); } } class Child extends Father{ public String name="ldson"; public void say() { System.out.println(name+" son"); } } public class Test{ public static void main(String[] args) { Father f=new Child(); System.out.println(f.name); //虽然子类和父类都有相同的成员变量,但是对于成员变量,并不会进行覆盖,而是并存 f.say(); //输出ldson son,可以知道,方法重写后,在子类的内存空间中不会存在父类的方法say } }
六:对象类型转换
类 Teacher 和 Student 是类 Person 的子类; Teacher t; Student s; // t and s are all non-null. if (t instanceof Person ){ s=(Student)t; } 最后一条语句的结果是:
A.将构造一个Student 对象;
B.表达式是合法的;
C.表达式是错误的;
D.编译时正确, 但运行时错误。
if判断没有问题,肯定是true,只是类型强制转换不能向这样转,只能在一个继承层次上由子类向父类强制转型。
class People{ } class Teacher extends People{ } class Student extends People{ } public class Elm{ public static void main(String[] args) { Teacher t=new Teacher(); Student s=new Student(); if(t instanceof People) { s=(Student)t; //Cannot cast from Teacher to Student } } }
子类向父类强转是允许的
public class Elm{ public static void main(String[] args) { Teacher t=new Teacher(); Student s=new Student(); People p=new People(); if(t instanceof People) { p=(People)t; } } }
父类向子类强转是编译可以通过,但是运行报错
public class Elm{ public static void main(String[] args) { Teacher t=new Teacher(); Student s=new Student(); People p=new People(); if(t instanceof People) { t = (Teacher)p; } } }