java多态2



1)构造器和多态
这个问题其实前面写过了,构造器实际上是static方法,只不过是隐式声明,所以构造器并没有多态性。
但是需要知道加载的顺序。
[java] view plaincopy
class GrandFather{
GrandFather(){
print();
}

private int print(){
System.out.println(“g”);
return 1;
}
}
class Father extends GrandFather{
Father(){
print();
}
private int print(){
System.out.println(“f”);
return 1;
}
}
public class Son extends Father{
Son(){
print();
}
private int print(){
System.out.println(“s”);
return 1;
}
public static void main(String[] args) {
Son s = new Son();
}
}

其实new出子类的时候,需要调用父类构造器,递归下去。
所以输出结果为g,f,s。

2)继承与清理
虽然有GC,但是书上还是用了一次引用技术的方法来模拟清理对象。
[java] view plaincopy
class Count{
private int reference;
private static int counter;
private final long id = counter++;//注意一下,虽然是final,或许会觉得它不是不可变
//为什么还给他赋值呢,对,但是现在值没确定,我们给他赋值之后就不会再变了。

Count(){
System.out.println(“count”+id);
}

public void addReference(){
reference ++;
}

protected void dispose(){
if(–reference == 0){
System.err.println(“dispose count”+id);
}
}
}

public class Rubbish {
private Count count;
private static int counter;
private final long id = counter++;

Rubbish(Count count){
System.out.println(“Rubbish”+id);
this.count = count;
this.count.addReference();
}


protected void dispose(){
System.out.println(“dispose Rubbish”+id);
count.dispose();
}

public static void main(String[] args) {
Count count = new Count();
Rubbish rubbish[] = {new Rubbish(count),new Rubbish(count),
new Rubbish(count),new Rubbish(count)};
for(Rubbish r:rubbish){
r.dispose();
}
}
}

每new一个对象的时候,计数器counter计算count对象的数量,id为final是我们确定之后不希望被改变,reference是引用计数,每每对象增加一个,便会加一,当引用都没有的时候,我们也要将计算引用的这个对象清理。
原来GC里面的引用计数法是这样的一个原理。

3)用继承进行设计
TV大变身:
[java] view plaincopy
class TV{
public String getString(){
return “tv”;
}

public TV change() {
// TODO Auto-generated method stub
return new TV();
}
}
class SanTV extends TV{
public String getString(){
return “santv”;
}
}
public class LeTV extends TV{
public String getString(){
return “letv”;
}
public SanTV change(){
return new SanTV();
}
public static void main(String[] args) {
TV letv = new LeTV();
System.out.println(letv.getString());
TV newtv = letv.change();
System.out.println(newtv.getString());
}
}

之前犯了一个错误,TV类里面是没有change方法的,我直接用了
[java] view plaincopy
TV newtv = letv.change();
发现报错,TV没有定义change方法,我子类不是可以有自己的新方法吗,为什么会报错?
后面搞明白了,父类引用指向子类对象,其实一开始调用的是父类的方法,由于多态的存在,后期绑定之后,才会结合具体的重写方法。但是我现在父类方法都没定义,肯定报错。为了验证,修改代码。
[java] view plaincopy
public class LeTV extends TV{
public String getString(){
return “letv”;
}
public static void main(String[] args) {
TV letv = new LeTV();
System.out.println(letv.getString());
TV newtv = letv.change();
System.out.println(newtv.getString());
}
}

现在子类没有重写change方法,默认就是继承父类的change方法,这样的输出结果就是letv,tv。

其实上面这种转换是一种特殊的模式——状态模式。
其实TV可以看成List,两个具体的TV可以看成LinkedList和ArrayList。两种状态可以灵活的切换。

多态就讲到这里了——不同的形式。
要真正的理解,实需多敲敲代码,写完之后自己会发现自己是用了多态。