注意点:
1.(注意应用) 静态变量和静态代码块,在类加载后,只执行一次!!!!!
2.继承时,在调用一个对象的方法时, 该对象是哪个类的对象就先找哪个类, 如果这个类中有指定方法就执行, 没有就找父类.!!!
3.一个父类引用可以指向一个子类对象, 但是这时不能调用子类特有的方法!!!
4.强制类型转换时, 不论类型是否匹配, 编译都不会报错, 运行时类型不匹配会抛出异常ClassCastException
所以,在强制类型转换之前, 通常都使用instanceof进行类型判断.
5.在重写方法时, 可以使用@Override来检查当前方法是否成功覆盖父类方法, 如果没有覆盖, 编译会报错.
6.创建子类对象的时, 会先创建一个父类对象!!!
7.子类没有指定调用父类的哪个构造函数时,会默认为调用父类的无参构造函数;父类若是没有无参的构造函数,则子类必须使用super关键字进行指定
一.static关键字:
1.用于修饰类的成员,与类的加载有关
2.静态变量
-修饰类的属性:
a.访问方式: 类名.变量名
b.在类加载后初始化
c.可以被整个类共享
注意:
(实际应用)当定义一个变量希望被共享, 或者类加载后就能使用时, 就定义为静态的.
3.静态方法
a.访问方式: 类名.方法名
b.在类加载后就可以被调用,但是不能访问非静态成员(注:可以先创建对象,再调用)
注意:
当定义一个方法时, 这个方法不需访问外部任何非静态成员(也不可以使用this关键字), 就可以定义为静态的, 如工具类
4.静态代码块
a.类加载后就执行
注意:
先是静态变量的默认初始化,接着静态代码块与静态变量,这两者按照声明的顺序进行执行
b.不能访问外部非静态成员(也不可以使用this关键字)
注意:
Person p; //这样并不会加载Person类;
(实际应用)当有一些代码希望在类加载之后就执行, 且只执行一次的时候, 就可以定义为静态代码块.
二.垃圾回收
1.finalize
在一个类中写了finalize方法之后, 对象销毁时会执行这个方法中的代码
2.gc
System.gc()可以通知虚拟机销毁内存中的垃圾对象
注意:
class Person {
static int count=0;
public static void main(String[] args) {
Person p = new Person();
count++;
p=null; //当p为null后,已经没有任何引用指向上面创建的对象,
//此时该对象成为垃圾
/*
for(int i=0;i<1000000;i++) { //为了能够看到调用finalize()方法的效果,i取值较大
new Person();
}
*/
for(int i=0;i<100;i++) {
new Person();
count++;
}
System.out.println(count);
System.gc(); //调用垃圾回收器,但不会立即执行,需要时间
try {
Thread.sleep(1000); //异常: InterruptedException
}catch(Exception e) {}
System.out.println(count);
}
@Override
public void finalize() {
System.out.println(“垃圾回收”);
count–;
}
}
三.单态设计模式-SingletonPattern
1.什么是单态设计模式
当定义一个类, 而希望这个类只能创建一个对象时, 可以使用单态设计模式
2.单态设计模式的步骤:
a.私有化构造函数
b.类内部创建对象, 用成员变量引用, 私有化防止类外修改
c.提供一个公有的静态的方法, 让类外可以获取到该对象
注意:
class Person {
//2.创建对象,使用成员变量指向它;需要static,下面的静态方法会访问它
private static final Person person = new Person();
//1.private构造函数
private Person() {
}
//3.提供方法给外部使用该单一对象
public static Person getInstance() {
return person;
}
}
四.继承-Inherit
1.什么是继承
一个类可以使用extends继承另一个类, 子类继承父类之后得到父类的所有成员.
(优点: 提高代码复用性)
2.继承的特点
Java只支持单继承, 不支持多继承, 但是可以多重继承.
3.类型转换
a.向上转换:
Person p = new Student();
子类对象可以当作父类对象使用, 因为父类有的子类都有.
注意:
一个父类引用可以指向一个子类对象, 但是这时不能调用子类特有的方法.
b.向下转换:
Person p = new Student();
Student s = (Student)p; //子类当父类用时, 如果要调用子类特有的方法, 可以使用强制类型转换将父类变量强转回子类.
注意:
强制类型转换时, 不论类型是否匹配, 编译都不会报错, 运行时类型不匹配会抛出异常ClassCastException
所以,在强制类型转换之前, 通常都使用instanceof进行类型判断.
Student s = null;
if(p instanceof Student) {
s = (Student)p;
}
4.重写方法-Override:
子类覆盖父类的方法时,
a.返回值类型, 方法名, 参数列表必须全部相同.
注意:
(jdk1.5开始,子类方法的返回值类型可以是父类方法的返回值类型的子类)
b.父类和子类的方法必须都是实例方法
c.不能定义更低的访问权限
d.子类方法抛出的异常不能比父类方法抛出的多,可以是父类抛出异常的子集
e.父类方法必须在子类中可见,即不能为public
注意:
a.可以使用”super.方法名”访问父类的方法.
b.在调用一个对象的方法时, 该对象是哪个类的对象就先找哪个类, 如果这个类中有指定方法就执行, 没有就找父类.
c.在重写方法时, 可以使用@Override来检查当前方法是否成功覆盖父类方法, 如果没有覆盖, 编译会报错.
如:
@Override
public void finalize() {
System.out.println(“垃圾回收”);
count–;
}
d.Overload的区别:
Overload的条件: 方法名相同,参数列表不同(参数类型,个数,顺序不同)
注意:重载与返回值类型无关!!
5.子类对象的创建:
a.创建子类对象的时, 会先创建一个父类对象.
b.在执行子类构造函数的时候, 会先执行父类构造函数.
注意:
a.子类没有指定调用父类的哪个构造函数时,会默认为调用父类的无参构造函数;
父类若是没有无参的构造函数,则子类必须使用super关键字进行指定
b.在构造函数中,super语句与this语句使用时都必须在第一行位置,所以无法共用,只能使用一个
c.对于:
A a = new B(); //B extends A
a.name; //打印: A (由引用类型决定)
a.fun(); //打印: B.fun (由对象的实际类型决定)