• 技术文章 >Java >java教程

    Java-面向对象-继承、多态、组合

    高洛峰高洛峰2016-11-17 14:17:08原创716

    继承的特点

    单继承:每个子类最多只有一个直接父类,注意是直接父类,间接父类个数不限

    注意父类的概念:A-->B-->C-->D,在这里,ABC都是D的父类,C是D的直接父类,AB是D的间接父类

    父类和子类是一般和特殊的关系;子类扩展了父类,子类是一种特殊的父类

    Object是所有类的直接或间接父类;定义一个类时,若没有直接指定父类,则默认继承Object类

    子类从父类继承了哪些要素

    子类不继承父类的构造方法,但是总要调用父类的构造方法

    子类继承了父类的实例变量和实例方法、类变量和类方法,当然前提是没有被private修饰

    父类中被private修饰的成员,不会被子类继承

    父类中用final修饰的方法,子类不能重写

    方法的重写override

    子类和父类拥有相同的方法签名,叫做子类重写了父类的方法

    两同两小一大原则:

    两同:方法名相同,形参列表相同

    两小:子类方法的返回值跟父类的相等或更小;子类方法抛出的异常要跟父类抛出的相等或更小

    一大:子类方法的访问权限要跟父类的相等或更大

    static:子类方法要跟父类方法一致,要么是类方法,要么是实例方法,二者不能不一致

    方法重写后,子类对象将无法访问父类的方法,但可以在子类方法中调用父类的方法:super.实例方法,父类名.类方法

    如果父类方法是private修饰,则子类不能重写该方法;如果子类拥有一个跟父类private方法相同签名的方法,这也不是重写,这是子类新添加的方法,与父类的无关

    子类方法可能会和父类的方法发生重载

    父类中用final修饰的方法,子类不能重写

    super关键字

    在子类中,用super关键字调用父类的实例变量或实例方法

    super和static不能同时用来修饰方法;就像this不能和static不能同时修饰方法一样

    子类从父类继承了一个变量,又再定义了一个变量,而且同名,此时可以用super.变量名或者父类名.变量名来访问父类的这个变量

    变量的查找顺序

    子类方法访问了一个变量,没有显式指定调用者的情况下,按以下顺序查找:

    当前方法中,是否有同名的局部变量

    当前类中,是否有同名的成员变量

    直接父类中,是否有

    逐级网上追溯,如果最终没有找到,那么提示编译出错

    super调用父类构造器

    子类虽然不会继承父类的构造器,但总是会调用父类的构造器。调用同一个类的构造器用this,调用父类的用super

    显式调用:super调用语句写在在构造方法的第一行,因为this也要写在第一行,因此super和this不会同时出现

    间接调用:子类方法的第一行写的是this,被调用的构造器还得调用父类的构造器

    隐式调用:无super无this,系统默认调用父类的无参构造

    子类继承父类,总会一级一级的往上调用父类构造器,直到调用Object的,并且是找到顶部父类构造器后,开始往下一层一层执行

    比如下面的代码,继承关系:A-->B-->C-->D

    public class Test{  
        public static void main(String[] args) {  
            D d=new D();
        }
    } 
    class D extends C{    D(){
            System.out.println("D类构造器");
        }
    }class C extends B{    C(){
            System.out.println("C类构造器");
        }
    }class B extends A{    B(){
            System.out.println("B类构造器");
        }
    }class A{    A(){
            System.out.println("A类构造器");
        }
    }

    输出:

    A类构造器
    B类构造器
    C类构造器
    D类构造器

    如果父类没有无参构造,子类又需要调用父类的无参构造,那么不能通过编译

    多态Polymorphism

    简单的说,多态就是:在一个金字塔式的继承体系中,创建底部子类对象时,用顶端的父类类型指向这些底部的子类对象,通过相同类型的引用变量调用同一个方法时,会出现不同的结果

    多态源于:继承+父类型的引用指向子类型的对象+方法的重写

    引用变量有两个类型,一个是编译时类型,一个是运行时类型

    向上转型:父类型引用指向子类型对象,向上转型由系统自动完成

    向上转型的情况下:通过父类型的引用可以调用子类重写了的方法,但不能访问父类中没有子类中才有的实例变量,也就是说实例变量不具有多态性

    instanceof与强制类型转换

    基本类型有强制类型转换,比如(double)16;引用类型也存在强制类型转换

    比如存在以下继承链:A-->B-->C-->D-->E-->F,B b=new D(),此时用B类型指向D对象,此时可以把b变量转为ACD类型,但不能转为EF类型,抛出异常ClassCastException

    进行强制类型转换之前,应先用instanceof进行判断能不能转,避免抛出异常

    X变量 instanceof Y类型:判断X变量能不能转为Y类型,可能出现三种情况:

    true表示可以转,意味着X变量指向的对象的类型,是Y类型或者Y的子类型;

    false表示不可以转,意味着X变量的类型与Y类型存在父子继承关系,不可能是子父关系,X变量指向的对象的类型与Y类型没有父子或子父关系,二者都是X变量类型的子类型;

    编译不通过,表示X和Y没有父子或者子父继承关系

    继承与组合

    继承可以实现代码的复用,但破坏了封装;组合也可以实现代码的复用

    设计父类遵循的原则:

    尽量用private隐藏父类的内部数据,不让子类直接访问父类的成员变量

    不要让子类随意访问、修改父类方法。父类辅助性的工具方法,用private修饰;需要让外部调用的方法,用public;不希望子类重写的方法用final修饰;希望子类重写而不希望外部访问则用protected

    不要在父类构造器中调用可能被子类重写的方法,后果很严重

    设计继承的原则:

    子类需要增加额外的属性,而不是属性的改变

    子类需要增加自己独有的功能或行为,可以增加新方法,或者重写父类方法

    不要光出于代码复用的目的设计继承,而要看实际情况,父类和子类是否有"has-a"的关系

    不想让一个类被继承:

    final:用final修饰该类为最终类,不能被继承

    private:用private修饰该类的所有构造方法,这样子类就无法调用该类的构造器,就不能继承了,另外应提供一个静态方法,用来返回该类的对象

    组合也能实现代码的复用

    A类复用B类的方法

    A类中创建B类的对象,并用private修饰

    在A类方法中调用B类对象的方法

    组合还是继承:

    继承:子类与父类是"is-a"关系,具体与抽象、特殊与一般的关系

    组合:新类与旧类是"has-a"关系,整体与局部的关系

    其他:

    对于子类从父类继承了一个变量,又定义了一个同名变量的情况下,在创建子类对象时,为这两个变量都分配了内存,只是父类变量被隐藏

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:Java
    上一篇:java学习指南 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • 一起来分析java设计模式之单例• Java数据结构之单链表与OJ题• 一文搞懂Java线程池实现原理• 详细介绍Java正则表达式之单字符匹配和预定义字符• Java总结分享之反射、枚举、Lambda表达式
    1/1

    PHP中文网