java 多态简述

来源:互联网 发布:java web书籍 编辑:程序博客网 时间:2024/05/12 09:55

java 三大基本特征:继承、 封装、多态

  1. 继承是java中对类之间关系的描述,如果多个类同时拥有相同的属性、行为就可以将其抽取成为基类, 然后子类分别继承于它,例如狗,猫,鸭子都有名字, 脚数量等属性,同时也有会吃,会叫等行为,所以可以将这些属性行为都抽取为动物类,至于它们行为的差异性可以通过继承后重写基类的方法实现。 其实java中的向上转型, 多态都是基于继承的。

    所谓向上转型就是让基类的引用指向子类的引用,其实这也就是上边所说的用来描述类之间的关系,因为可以说子类是基类(狗是动物),而在多数情况下, 使用继承的原因也是为了提供这样的一个关系。

2.封装就是打包、包装、数据隐藏的意思,也就是将某个事物的属性,行为封装到一个类中, 然后将这些东西隐藏,同时提供一下让人知道它们拥有这些行为的接口, 如:我们知道狗会吃东西,会叫,但是它们吃东西然后消化、叫时时怎么发出声音这些细节我们不需要知道。

    使用封装有三大好处:     1、良好的封装能够减少耦合。     2、类内部的结构可以自由修改。     3、可以对成员进行更精确的控制。     4、隐藏信息,实现细节。

3.多态就是一个类的引用在不同的状态下回呈现出不同的状态, 看代码:

package com.mjlf.myBatis.accessControl.animal;/** * Created by a123 on 16/12/11. */public class Animal {    public void eat(){        System.out.println("animal eat");    }    public void cry(){        System.out.println("animal cry");    }    public static void main(String[] args){        Animal animal = new Animal();        Animal animal1 = new Dog();//向上转型,用基类的引用指向子类的引用        Animal animal2 = new Cat();        animal.cry();        animal1.cry();        animal2.cry();    }}class Dog extends Animal{    public void eat(){        System.out.println("dog eat");    }    public void cry(){        System.out.println("dog cry");    }}class Cat extends Animal{    public void eat(){        System.out.println("cat eat");    }    public void cry(){        System.out.println("cat cry");    }}/**animal crydog crycat cry从输出结果可以发现, 同样是Animal类的对象,同样是调用cry()方法,但是输出的接口去完全不一样, 这就是多态。*/

注意:
1. 子类只能继承基类共有或protected的属性和方法, 在使用多态的时候要注意这一点,见下例:

package com.mjlf.myBatis.accessControl.animal;/** * Created by a123 on 16/12/11. */public class Animal {    private void owns(){        System.out.println("myself function");    }    public static void main(String[] args){        Animal animal = new Animal();        Animal animal1 = new Dog();        Animal animal2 = new Cat();        animal.owns();        animal1.owns();        animal2.owns();    }}class Dog extends Animal{    private void owns(){        System.out.println("dog function");    }}class Cat extends Animal{    private void owns(){        System.out.println("cat function");    }}/** myself function myself function myself function 根据上一例所说, 这里应该输出的是 myself function dog function cat function 但是却不是,所以可以发现子类不能继承基类的private 方法,当然属性也是如此。 */

如果是默认权限修饰, 是否可以被继承呢?

//同步实验package com.mjlf.myBatis.accessControl.animal;/** * Created by a123 on 16/12/11. */public class Animal {    void owns(){        System.out.println("myself function");    }    public static void main(String[] args){        Animal animal = new Animal();        Animal animal1 = new Dog();        Animal animal2 = new Cat();        animal.owns();        animal1.owns();        animal2.owns();    }}class Dog extends Animal{    void owns(){        System.out.println("dog function");    }}class Cat extends Animal{    void owns(){        System.out.println("cat function");    }}/** myself function dog function cat function */
//不同包中实验package com.mjlf.myBatis.accessControl.entity;import com.mjlf.myBatis.accessControl.animal.Animal;public class Cat extends Animal {    void owns(){        System.out.println("cat function");    }}
package com.mjlf.myBatis.accessControl.entity;import com.mjlf.myBatis.accessControl.animal.Animal;public class Dog extends Animal {    void owns(){        System.out.println("dog function");    }}
package com.mjlf.myBatis.accessControl.animal;import com.mjlf.myBatis.accessControl.entity.Cat;import com.mjlf.myBatis.accessControl.entity.Dog;/** * Created by a123 on 16/12/11. */public class Animal {    void owns(){        System.out.println("myself function");    }    public static void main(String[] args){        Animal animal = new Animal();        Animal animal1 = new Dog();        Animal animal2 = new Cat();        animal.owns();        animal1.owns();        animal2.owns();    }}/*myself functionmyself functionmyself function根据上述两个实验可以知道,在同一包中,默认权限修饰的方法是可以被重写的,但是在不同包中就不能被重写*/

2.继承中不能继承基类静态方法, 同时也要注意继承中的属性的使用, 否则会出现意想不到的结果

package com.mjlf.myBatis.accessControl.animal;/** * Created by a123 on 16/12/11. */public class Super {    public int field = 0;    public int getField() {        return field;    }    public static void main(String[] args){        Super sup = new Sub();        System.out.println("sup.field : " + sup.field + " sup.getField() :" + sup.getField());        Sub sub = new Sub();        System.out.println("sub.field : " + sub.field + " sub.getField() :" + sub.getField() +        " sub.getSuperField() :" +sub.getSuperField());    }}class Sub extends Super{    public int field = 1;    public int getField() {        return field;    }    public int getSuperField(){        return super.getField();    }}/*sup.field : 0 sup.getField() :1sub.field : 1 sub.getField() :1 sub.getSuperField() :0可以发现调用sup.field是值为0, 说明是Super类的field属性,也就是在基类和子类中同时拥有相同的是属性时,通过基类对象.属性名调用的是基类的属性, 不会出现多态效果, 但是如果调用其属性的get方法,则得到子类对象该属性的值, 因为在这里出现多态效果,在使用时必须注意这一点,如果在子类对象中想获取基类对象中的该属性的值, 可以通过super对象调用,在继承关系中,super表示子类对象的上一级基类对象 */

上述情况需要注意,但是最后一种情况一般不会出现,在实际开发过程中很少有人会将在子类中取名属性和基类完全相同,即使相同, 在封装中我们也说道,一般所有的属性都是对外隐藏的。

0 0
原创粉丝点击