1:java创建对象的几种方法:
| 1,2都会明确地调用构造函数 3是在内存上对已有对象的影印,所以不会调用构造函数 4是从文件中还原类的对象,也不会调用构造函数。
|
2:java的容器类库一共有两种主要类型:Collection和Map
他俩的主要区别在于每个槽内存储的个数不同:Collection每个槽只有一个元素;Map类型中每个槽都有key-value;
容器类与Array的区别:
·容器类仅能持有对象引用(指向对象的指针),而不是将对象的信息复制。一旦将对象置入容器中,便失去了对象的类别信息。
在List中Vector总比ArrayList(其可以重复)慢;
在set中HashSet通常优于HashTree(用来维护其内元素的排序状态),当需要产生排序的序列时,才使用TreeSet;
在Map中HashMap用于快速查找;
·当元素个数固定时,最好使用Array(其效率最高)。
HashTable与HashMap的区别:
他们都属于Map接口的类,实现将唯一键映射到特定的值上;
HashMap类没有分类或者排序,它允许一个null键和多个null值; 不能包含重复键,但可以包含重复值
有containsvalue和containsKey方法判断存在;
HashMap必须为多线程提供外同步;HashMap不是线程安全的
HashTable类不允许null键与null值,比HashMap慢,因为他是同步的(多线程时不同步);
有contains方法;
有Synchronize方法,在多线程访问Hashtable时,不需要为此方法实现同步;HashTable是线程安全的一个Collection
3:普通类方法和类名相同,构造函数必须同名,他俩唯一的区别是构造函数没有返回值;;;
派生类的构造函数调用时必须先调用父类构造函数;;;(以下代码输出为:YXYZ)
class X{
Y y = new Y();///步骤1:z继承x,构造z前先构造x,所以先执行此行
X(){ System.out.println("X");}///步骤2:输出x
}
class Y{
Y(){ System.out.println("Y"); }
}
public class Z extends X{
Y y =new Y();///步骤3:又一次输出y
Z(){ System.out.println("Z"); }///步骤4:调用z本身的构造函数
public static void main (String [] args) {
new Z();
}
}
4:
派生类被构造是会先调用父类的构造函数,可以选择哪个构造函数,如不指定就会调用无参数的构造函数(如下左);
如指定就会根据指定的来(如下右)
class A{ public A() {System.out.println("A0");} public A(int i) {System.out.println("Ai");} } class B extends A{ public B() {System.out.println("B0");} public B(int i) {System.out.println("Bi");} } class Test{ public static void main (String [] args) { B a = new B(100); } } | class A{ public A() {System.out.println("A0");} public A(int i) {System.out.println("Ai");} } class B extends A{ public B() {System.out.println("B0");} public B(int i) {super(i);System.out.println("Bi");} } class Test{ public static void main (String [] args) { B a = new B(100); } } |
会先执行A(),在执行B(i) 输出结果: A0 Bi B a = new B();///会输出 A0 B0 A a = new B();///会输出 A0 B0 | 会先执行A(i),在执行B(i) 输出结果: Ai Bi A a = new B(100);///会输出 Ai Bi |
5:多态
多态性概括为“一个接口,多种方法”;在运行过程中才会决定哪个函数,
虚函数就是允许被子类重新定义的成员函数。而子类重新定义父类虚函数的做法被称为“覆盖override”或重写;
覆盖和重载(overload):
重载是允许存在多个同名函数,他们的参数不同;而重载不属于面向对象编程,重载的实现:编译器根据函数的参数,当调用他们时,编译期间就已经确定了,是静态的,因此重载与多态无关;重载只是一种语法规则;
覆盖是指子类重新定义父类虚函数的做法; 与多态相关,当子类重新定义父类的虚函数后,父类指针根据赋给它不同的子类指针,动态调用属于子类的该函数,编译期间无法确定函数调用。
多态的作用:封装可以隐藏实现细节,是代码模块化,继承可以扩展已存在的代码模块。他们的目的为了代码重用。
多态是为了接口重用,
6:
public class NULL{ public static void h(){ System.out.println(“hhh”); } public static void main(String [] args){ ((NULL)null).h(); } } | 输出结果为hhh 因为null值可以强制转换为任何java类型,(String)null也是合法的。 但是null强制转换后是无效对象,其返回值还是null;而static方法的调用时和类名绑定的,不借助对象的访问,所以可以输出hhh 如果没有static(第2行)修饰,那么只能使用对象进行访问,使用null调用对象肯定会报错 |