面向对象复习
深刻理解,需要弄明白的问题:
1,Static关键字的意思?
2,Static关键字可修饰什么,基本使用规则?
3,Static关键字可修饰同步方法吗?
4,静态内部类和非静态内部类的区别?
构造器中要注意的地方:
构造器不能声明返回值类型,也不能用void声明没有返回值
如果加了,虚拟机会把“构造器”当作普通方法执行
构造器是否创建对象?
大部分时候,程序是通过new关键字来为java对象申请空间,然后通过构造器来初始化对象,所以事实上构造器只负责初始化对象
下面两种情况在创建对象时无序调用构造器:
1, 使用反序列化的方式恢复java对象
2, 使用clone方法复制java对象
首先:对象必须被序列化
第一种方式,就是将java对象保存到本地文件中,再通过读取本地文件从而读取java对象
代码如下:
public class SerializableTest {
public static void main(String[] args) throws Exception {
// 将对象写入硬盘中
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"F:\\3\\object1.txt"));
Person p = new Person("zhangsan");
oos.writeObject(p);
oos.flush();
// 从硬盘中读取对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
"F:\\3\\object1.txt"));
Person p1 = (Person) ois.readObject();
System.out.println(p.equals(p1));
// 可以看出p和p1是两个对象
System.out.println(p == p1);
}
}
可能破坏单例:为了避免,应该给单例类提供readResolve()方法,返回已有的实例对象
第二种方式:使对象实现Cloneable接口,重写clone()方法,就可以调用该对象的clone方法来创建对象 了
class Dog implements Cloneable {
private String name;
public Dog(String name) {
System.out.println("调用带有参数的构造方法");
this.name = name;
}
public Object clone() {
Dog dog = null;
try {
// 调用Object类的clone()方法
dog = (Dog) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return dog;
}
// 从写equals方法
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj.getClass() == Dog.class) {
Dog target = (Dog) obj;
return target.name.equals(this.name);
}
return false;
}
}
public class CloneTest {
public static void main(String[] args) {
// 调用带参数的构造器
Dog dog = new Dog("aoli");
// 并没有调用构造器
Dog dog2 = (Dog) dog.clone();
// 输出true
System.out.println(dog.equals(dog2));
// 输入false
System.out.println(dog == dog2);
}
}
方法重写需要注意的问题
子类无法访问父类中的private方法和属性,父类中定义的private方法不可能被子类重写
如果不使用任何访问控制符修饰方法,则就是默认的default修饰,该访问权限限定在只能是与该类处于同一包内的其他类访问,其他包中的子类依然无法访问该方法
非静态内部类:
内部类可以直接访问外部类的private成员
内部类访问外部类的局部变量时,局部变量需要final修饰(详情见blog:java编程细节01)
创建非静态内部类的对象时,需要创建一个外部类对象,作为参数传入内部类的构造器,因此,内部类的构造器的第一个形参总是外部类(所以说,非静态内部类是依赖于外部类的)
一点:在外部类里面派生内部类的子类是安全的,因为派生出来的子类也是内部类,也是依赖于外部类的。
但是在外部类外面派生内部类的子类,需要在子类无参构造器中显示调动父类指定的构造器
1, Static
表示静态
2, static关键字可修饰成员变量和成员函数
成员变脸被static修饰后的特点:
随着类的加载而加载
优先于对象存在
被所有对象所共享(多个实例的静态变量共享同一块内存空间)
可以直接被类名调用
使用规则:
静态方法只能访问静态成员
静态方法中不可以写this,super关键字
Static只能用于修饰在类中定义的成员,包括:Field,方法,内部类,初始化块,内部枚举类
Static修饰方法时,该方法是静态方法,属于类,所以不能被子类重写
3,Static关键字可修饰同步方法吗?
可以:
Static修饰的同步方法,拿到的锁不是实例对象,而是该类的Class文件,就是当前类
4,静态内部类与非静态内部类的区别:
静态内部类,不像非静态内部类属于外部类一样,创建静态内部类对象不需要先创建外部类实例对象,只要通过外部类名调用就行,如下:
class Outer {
private String name;
private static int age;
public static class Inner {
public void info() {
// 可以直接访问外部类的静态成员
System.out.println("age:" + age);
}
}
}
public class InnerTest {
public static void main(String[] args){
// 静态内部类,不用先创建外部类实例对象
Outer.Inner in = new Outer.Inner();
in.info();
}
}