Java编程思想(五) —— 多态(下)

多态(上)基本讲解了很多多态的特性和问题。下面继续。

1)构造器和多态

这个问题其实前面写过了,构造器实际上是static方法,只不过是隐式声明,所以构造器并没有多态性。

但是需要知道加载的顺序。

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,但是书上还是用了一次引用技术的方法来模拟清理对象。

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大变身:

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方法的,我直接用了

TV newtv = letv.change();

发现报错,TV没有定义change方法,我子类不是可以有自己的新方法吗,为什么会报错?

后面搞明白了,父类引用指向子类对象,其实一开始调用的是父类的方法,由于多态的存在,后期绑定之后,才会结合具体的重写方法。但是我现在父类方法都没定义,肯定报错。为了验证,修改代码。

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。两种状态可以灵活的切换。

多态就讲到这里了——不同的形式。

要真正的理解,实需多敲敲代码,写完之后自己会发现自己是用了多态。

时间: 2024-11-08 21:38:35

Java编程思想(五) —— 多态(下)的相关文章

Java编程思想(五) —— 多态(上)

上一章,Java编程思想(四) -- 复用类里面讲到了向上转型,感觉和多态放在一起写更好. 多态,polymorphism.一个重要的特性,篇幅太长了,分上下两篇写. (1)向上转型 class TV{ public static void show(TV tv){ System.out.println("TV"); } } public class LeTV extends TV{ public static void main(String[] args) { LeTV letv

JAVA编程思想(4) - 多态(一)

多态 在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种基本类型. 多态通过分离做什么和怎么做,从另一个角度将接口和实现分离开来.多态不但能够改善代码的组织结构和可读性,还能够创建可扩展程序. 再论向上转型 代码 //: polymorphism/music/Note.java // Notes to play on musical instruments. package polymorphism.music; public enum Note { MIDDLE_C, C_SHAR

JAVA编程思想(4) - 多态(三)

若干个对象共享 例如Frog对象拥有其自己的对象,并且知道他们的存活多久,因为Frog对象知道何时调用dispose()去释放其对象.然而,如果这些成员对象中存在于其他一个或多个对象共享的情况,问题将不再简单,不再能简单的调用dispose()了.在这种情况下,我们也许需要引用计数来跟踪依旧访问着共享对象的数量. //: polymorphism/ReferenceCounting.java // Cleaning up shared member objects. import static

Java编程思想(四) —— 复用类

看了老罗罗升阳的专访,情不自禁地佩服,很年轻,我之前以为和罗永浩一个级别的年龄,也是见过的不是初高中编程的一位大牛之一,专访之后,发现老罗也是一步一个脚印的人.别说什么难做,做不了,你根本就没去尝试,也没有去坚持. If you can't fly then run,if you can't run then walk, if you can't walk then crawl,but whatever you do,you have to keep moving forward--Martin

Java编程思想之8多态

这一章看下来,感觉比较混乱.乱感觉主要乱在8.4  8.5. 开始读的时候,感觉8.1 8.2 8.3都挺乱的.读了两遍后发现前三节还是比较有条理的. 8.1主要讲了什么是多态,多态的好处. 8.2主要讲了什么情况会发生多态?? 8.3主要讲了构造器内部里面的方法调用会发生多态. 8.4就一页,而且感觉一般用不到.用到了再看也行. 8.5也很简单,相当于一个总结,一个补充(向下转型) 我主要根据书上的内容,总结两个内容: 1.什么是多态,多态的好处: 2.什么情况下会发生多态?为什么这些情况下会

《On Java 8》中文版,又名《Java 编程思想》中文第五版

来源:LingCoder/OnJava8 主译: LingCoder 参译: LortSir 校对:nickChenyx E-mail: [email protected] 本书原作者为 [美] Bruce Eckel,即(Thinking in Java 4th Edition,2006)的作者. 本书是事实上的 Thinking in Java 5th Edition(On Java 8,2017). Thinking in Java 4th Edition 基于 JAVA 5 版本:On

Java 编程思想 第五章 ----初始化与清理(1)

从今天开始每天一小时的java 编程思想的阅读和编码,其实就是把书上的代码抄下来. 5.5 清理:终结处理和垃圾回收 初始化和清理工作同等重要,但是清理工作却被常常忘记,但是在使用对象之后,对对象弃之不顾的做法并不是很安全.Java有自己的垃圾回收器负责回收无用的对象占据的内存资源.但也有特殊情况:假定你的内存区域不是用new获得的,这是无法用垃圾回收器释放所以java中允许在类中定义一个名为 finalize()的方法.       工作原理: 一旦垃圾回收器准备好释放对象占用的存储空间,将首

JAVA编程思想读书笔记(五)--多线程

接上篇JAVA编程思想读书笔记(四)--对象的克隆 No1: daemon Thread(守护线程) 参考http://blog.csdn.net/pony_maggie/article/details/42441895 daemon是相于user线程而言的,可以理解为一种运行在后台的服务线程,比如时钟处理线程.idle线程.垃圾回收线程等都是daemon线程. daemon线程有个特点就是"比较次要",程序中如果所有的user线程都结束了,那这个程序本身就结束了,不管daemon是否

Java 编程思想 Chapter_14 类型信息

本章内容绕不开一个名词:RTTI(Run-time Type Identification) 运行时期的类型识别 知乎上有人推断作者是从C++中引入这个概念的,反正也无所谓,理解并能串联本章知识才是最重要的 本章的内容其实都是为类型信息服务的,主要内容有 一.Class对象 问题: 1.Class对象的创建过程是怎么样的 2.Class对象有哪几种创建方式,之间有什么差异 3.使用泛型 在了解类型信息之前,需要了解class对象 创建class对象,需要先查找这个这个类的.class文件, 查找