java 多态简述

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 cry
dog cry
cat 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 function
myself function
myself 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() :1
sub.field : 1 sub.getField() :1 sub.getSuperField() :0
可以发现调用sup.field是值为0, 说明是Super类的field属性,也就是在基类和子类中同时拥有相同的是属性时,通过基类对象.属性名调用的是基类的属性, 不会出现多态效果, 但是如果调用其属性的get方法,则得到子类对象该属性的值, 因为在这里出现多态效果,在使用时必须注意这一点,如果在子类对象中想获取基类对象中的该属性的值, 可以通过super对象调用,在继承关系中,super表示子类对象的上一级基类对象
 */

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JAVA多态的三种形式分别是重写、重载和接口实现。 1. 重写(Override):子类继承父类后,可以对父类中的方法进行重写,即在子类中重新定义一个与父类方法名、返回值类型和参数列表都相同的方法,但是方法体不同。当调用该方法时,会根据对象的实际类型来确定调用哪个方法。 2. 重载(Overload):在同一个类中,可以定义多个方法名相同但参数列表不同的方法,这就是方法的重载。当调用该方法时,会根据传入的参数类型和数量来确定调用哪个方法。 3. 接口实现(Interface):接口是一种抽象类型,它只定义了方法的声明而没有方法的实现。一个类可以实现一个或多个接口,实现接口的类必须实现接口中定义的所有方法。当调用实现接口的类的方法时,会根据对象的实际类型来确定调用哪个方法。 下面是三种形式的示例代码: 1. 重写 ```java class Animal { public void move() { System.out.println("动物可以移动"); } } class Dog extends Animal { public void move() { System.out.println("狗可以跑和走"); } } public class TestDog { public static void main(String args[]) { Animal a = new Animal(); // Animal 对象 Animal b = new Dog(); // Dog 对象 a.move();// 执行 Animal 类的方法 b.move();//执行 Dog 类的方法 } } ``` 输出结果为: ``` 动物可以移动 狗可以跑和走 ``` 2. 重载 ```java public class OverloadTest { public void test() { System.out.println("无参数"); } public void test(int a) { System.out.println("a: " + a); } public void test(int a, int b) { System.out.println("a: " + a + ", b: " + b); } public static void main(String[] args) { OverloadTest test = new OverloadTest(); test.test(); test.test(10); test.test(10, 20); } } ``` 输出结果为: ``` 无参数 a: 10 a: 10, b: 20 ``` 3. 接口实现 ```java interface Animal { public void eat(); } class Dog implements Animal { public void eat() { System.out.println("狗吃肉"); } } class Cat implements Animal { public void eat() { System.out.println("猫吃鱼"); } } public class TestAnimal { public static void main(String args[]) { Animal a = new Dog(); // Dog 对象 Animal b = new Cat(); // Cat 对象 a.eat();// 执行 Dog 类的方法 b.eat();//执行 Cat 类的方法 } } ``` 输出结果为: ``` 狗吃肉 猫吃鱼 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值