Java基础8--单例设计模式--继承(二)

2014-11-24 08:04:57 · 作者: · 浏览: 2
; } } class B { void show() { System.out.println("b"); } } class C extends A,B{ public static void main(String[] args) { new C().show(); } }

C类继承了A和B类,创建了C对象,调用show方法,但是A和B中都有show方法,这时就不知道调用哪个类的show方法。

所以Java不直接支持多重继承的原因就是:会产生调用的不确定性。

4,Java支持多层继承

如:C extends B , B extends A,这样会出现继承体系。

当要使用一个继承体系时:

(1)查看该体系的顶层类,了解该体系的基本功能。

(2)创建该体系的最子类对象,完成功能的调用。

Java中的多继承是通过多实现的方式体现出来的,也就是通过接口的方式体现。

5,什么时候定义继承呢?

当类与类之间存在着所属关系的时候,就定义继承。

Xxx是Yyy的一种。Xxx extendsYyy。

所属关系就是is a的关系。

8-9,子父类中成员变量的特点:

1,特点:

(1)成员变量

(2)成员函数

(3)构造函数

2,当本类的成员和局部变量同名用this区分。

当子父类中的成员变量同名时用super来区分。

This:代表一个本类对象的引用。

Super:代表一个父类空间,不代表父类对象,因为不用创建父类对象就可以用super引用父类。

例如:

class Fu {
	int num = 4;
}
class Zi extends Fu {
	int num = 5;
	void show() {
		System.out.println(this.num + "..." + super.num);
	}
}
class Demo {
	public static void main(String[] args) {
		Zi zi = new Zi();
		zi.show();
	}
}

结果:5...4

上例的内存图解:

\

首先主类Demo加载进内存,将方法加载进方法区,main加载进静态方法区(没有画出)。

然后main函数进栈,局部变量z进栈。

在堆中创建Zi的对象,JVM发现这个Zi类有个父类Fu,所以先加载其父类,先将父类的成员变量加载到Zi的单独的一片空间中,先加载父类是因为子类要用到父类的内容,那么父类就必须先初始化,否则子类无法使用。

然后将这个地址引用赋给main中的z,z指向堆内存的对象。

调用show函数,先在Zi的方法区中找这个方法,找到了,直接进栈执行,执行完毕之后,弹栈。

注意:如果这个show不是定义在子类,而是定义在父类中,那么上面这一步在Zi类方法区中是找不到show方法的,他就会通过Zi中的super引用去父类中找,如果找到,则执行,如果还没有,会到Object中找(所有类都继承自Object),如果有则执行,如果还没有,则报NoSuchMethod没有这个方法异常。

通过这个分析可以看出,super并不是指向的对象,而只是子类对父类的一个指向而已。

8-10,子父类中成员函数的特点-覆盖

1,当子父类中出现成员函数一模一样的情况,会运行子类的函数。

这种现象,称为覆盖操作,这是函数在子父类中的特性。

2,函数的两个特性

(1)重载:在同一个类中。

(2)覆盖:在子类中,也成为重写,覆写。

3,覆盖注意事项

(1)子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限。

(2)静态只能覆盖静态,或被静态覆盖。

如果父类方法为private,则子类无法对这个方法进行覆盖,因为私有化以后子类将无法看到这个方法,就谈不上覆盖了。

8-11,覆盖的应用

什么时候使用覆盖操作?

当对一个类进行子类的扩展时,子类需要保留父类的功能声明,但是要定义子类中该功能的特有内容时,就是用覆盖操作完成。

class Phone {
	void call() {}
	void show() {
		sop("number");
	}
}
class NewPhone extends Phone {
	void show() {
		sop("name");
		sop("pic");
		super.show();
	}
}