面向对象复习,深入理解static关键字


面向对象复习

深刻理解,需要弄明白的问题:

         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();
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章