java不充许多继承是,为了避免“致命方块”的出现
例如 B继承A,C继承A。 C和C里面都有play()方法 。
现在D继承了B,C 想想D.play()调用 的是哪个play()呢,这就是问题所在。
所以java提供了接口来解决此问题。
问:接口并不是真正的多重继承,因为你无法在它里面实现程序代码,
不是吗?如果是这样,那还要接口做什么?
答:多态,多态,多态。接口有无比的适用性,若你以接口取代具体的子类或
抽象的父类作为参数或返回类型,则你就可以传入任何有实现该接口的东西。
这么说吧,使用接口你就可以继承超过一个以上的来源。类可以 extend过某个父类
,并且实现其他的接口。同时其它的类也可以实现同一个接口。因此你就可以为不同的需求组合出不同的继承层次。
事实上,如果使用接口来编写程序,你就是在说:“不管你来自哪里,只要你实现这个接口,别人就会知道你
一定会履行这个合约”。
大部分良好的设计也不需要在抽象的层次定义出实现细节,我们所需的只是个共同的合约定义。让细节在具体的
子类上实现也是很合理的。
接口可以做为方法的参数 。只要实现过这个接口的类,都可以做为参数传入这个方法。
要如何判断应该是设计类、子类、抽象类或接口呢?
1、如果新的类无法对其它的类通过is-a测试时,就设计不继承其它类的类。
2、只有在需要某类的特殊化版本时,以覆盖或增加新的方法来继承现有的类。
3、当你需要定义一群子类的模板,又不想让程序员初始化些模板时(不想让程序员直接用它),设计出抽象的类给
它们用。
4、如果想要定义出类可以扮演的角色,使用接口。
构造器与垃圾回收机制
栈与堆:生存空间
在java中,程序员会在乎内存中的两种区域:
1、对象生存空间堆(heap)
2、方法调用及变量的生存空间栈(stack)。
实例变量是被声明在类而不是方法里面。
局部变量和方法的参数都是被声明在方法中的。在栈上。
栈顶上方法是目前正在执行中的。
二、创建对象的奇迹。
声明对象和赋值有三个步骤:
声明引用变量,创建对象,连接对象和引用。
声明引用变量
Duck myduck
创建对象
new Duck()
连接对象和引用
Duck myduck = new Duck()
如果你写了构造函数,则编译器就不会再给你构建默认的构造函数。
实例变量有默认值,原始类型的默认值是 0/0.0/false,引用类型的默认值是null
在创建新对象时,所有继承下来的无参构造函数都会执行。
执行new的指令是个重大事件,它会启动构造函数连锁反应。
还有,就算是抽象的类也有构造函数。虽然你不能对抽象的类执行
new操作,但抽象的类还是父类,因此它的构造函数会在具体子类
创建出实例时执行。
调用父类的构造函数用super()方法。他必须定在子类构造不函数的第一个语句。
父类的构造函数有参数时,继承的子类也必须super(相应的参数),才能继承。
如果有个重载版的构造函数,有个构造函数的代码要重复使用。就可以用this()或this("a")或this(67,x)
this()只能用在构造函数中,且它必须是第一行语句!
这样会跟super()起冲突吗?
所以必须选择:
每个构造函数可以选择调用super()或this(),但不能同时调用。
三、对像的生命周期。
对象的生命周期完全要看引用 到它的“引用”。引用活着,则对象也活在堆上。
如果引用死了,对象就殉情了。
1、局部变量只会存活在声明该变量的方法中。
2、实例变量的寿命与对象相同。如果对象还活着,则实例变量也会是活的。
当最后一个引用消失时,对象就会变成可回收的。
有3种方法 可以释放对象的引用。
1、引用永久性的离开它的范围。
void go(){
Life z = new Life();//z会在方法结束时消失。
}
2、引用被赋值到其他的对象上。
Life z = new Life();
z = new Life();
3、直接将引用设定为null
Life z = new Life();
z = null;
非静态方法与静态方法的差别。
以引用变量的名称调用非静态的方法。
取得新对象的方法只有通过new或者序列化(deserialization)以及我们不会讨论的java ReflectionAPI。
静态方法没有对象实例的,所以也不存在this。
所以静态方法不能调用非静态的变量和方法 。
静态变量它的值对所有的实例来说都相同。
静态变量只初始化一次,
静态变量是共享的。
同一类所有的实例共享一份静态变量。
实例变量:每个实例一个。
静态变量:每个类一个。
静态的final变量是常数。常数变量的名称应该大写。
final的静态变量值必须在声明或静态初始化程序中赋值:
static{
DOG_CODE = 40;
}
final也可以用来防止方法的覆盖或创建子类。
final的变量代表你不能改变它的值。
final的method代表你不能覆盖掉该method。
final的类代表你不能继承该类(也就是创建它的子类)