【java】多态

java多态

  • 多态的基本概念
  • 重载
    • 案例一
    • 案例二
  • 重写

多态的基本概念

多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:
【java】多态_第1张图片
多态性是对象多种表现形式的体现。

现实中,比如我们按下 F1 键这个动作:

  • 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
  • 如果当前在 Word 下弹出的就是 Word 帮助;
  • 在 Windows 下弹出的就是 Windows 帮助和支持。

同一个事件发生在不同的对象上会产生不同的结果。


下面代码中,创建了人的类,也创建了男人和女人的类,男人和女人都继承了人的类。

class Person {
    void testPerson() {
        System.out.println("test person...");
    }
}
class Boy extends Person {

    void testBoy() {
        System.out.println("test boy...");
    }
}
class Girl extends Person {

    void testGirl() {
        System.out.println("test girl...");
    }

我们可以看见使用多态时,p1和p2无法调用boy和girl的方法,这说明,多态语法其实就是对对象的使用场景进行了约束,比如说蜘蛛侠在不变身的情况下,一般不能使用蜘蛛侠的能力,但当变身后就可以使用能力了。

【java】多态_第2张图片

一个对象可以使用的功能取决于引用变量的类型。

多态的实现方式大致有三种:重写、接口、抽象类和抽象方法;接下来我们对重写和重载进行详细的介绍,抽象类会在后面的章节学习。

重载

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

public class Java14_Object {
    public static void main(String[] args) {
    
        user.login(1111);
        user.login("123123");
        user.login("zhangsan", "123123");

    }
}
class User14 {

    void login( String account, String password ) {
        System.out.println("账号,密码登录");
    }
    void login(int tel) {
        System.out.println("手机验证码登录");
    }
    void login(String wx) {
        System.out.println("微信,支付宝登录");
    }
}

当然,构造方法也有重载的功能。

public class Java14_Object {
    public static void main(String[] args) {

        User14 user = new User14("zhangsan");
    }
}
class User14 {

    User14() {
        System.out.println("user...");
    }
    User14(String name) {
        System.out.println("user..." + name);
    }

}

如果在一个构造方法中。想要调用其他的构造方法,那么需要使用特殊的关键字:this

public class Java14_Object_1 {
    public static void main(String[] args) {

        User141 user1 = new User141();
    }
}
class User141 {
    User141() {
        this("zhangsan");
    }
    User141( String name ) {
        this(name, "男");
    }
    User141( String name, String sex ) {
        System.out.println(name + "," + sex);
    }
}

【java】多态_第3张图片

案例一

下面再看一个重载的例子:

public class chapter10 {
    public static void main(String[] args) {

        byte b = 10;
      	test(b);
    }

//    static void test( byte b ) {
//        System.out.println("bbb");
//    }
    static void test( short s ) {
        System.out.println("sss");
    }
    static void test( char c ) {
        System.out.println("ccc");
    }
    static void test( int i ) {
        System.out.println("iii");
    }
}

从上面来看,如果是调用test (byte b),那毫无疑问是打印出bbb,但现在我们将test (byte b)进行注释,这个时候test (b)又会调用哪个呢?

【java】多态_第4张图片
结果是sss,说明调用了test (short s),可是为什么呢?
原因是基本数据类型在匹配方法时,可以在数值不变的情况下,扩大数据的精度

byte 8位
short 16位
char 16位
int 32位

所以,在没有byte的情况下,会默认匹配short。

现在我们又注释了test (short s),可以发现结果打印出iii,说明调用的是 test( int i )。
原因是,byte类型无法和char类型做转换,char没有负数,但是byte存在负数

案例二

我们再来看一个多态与重载相关的例子。
// 多态其实就是约束了对象的使用场景
// 方法的重载:方法名相同,参数列表不同(个数,顺序,类型)
// AAA -> Object
// BBB -> AAA -> Object

public class Java14_Object_3 {
    public static void main(String[] args) {

        AAA aaa = new BBB();
        test(aaa);

    }
    static void test( Object aaa ) {
        System.out.println("aaa");
    }
    static void test( BBB bbb ) {
        System.out.println("bbb");
    }
}
class AAA {

}
class BBB extends AAA {

}

以上运行结果是:aaa,说明方法的重载和调用的是类型。

如果现在将 static void test( Object aaa ) 注释掉呢?

【java】多态_第5张图片
结果test(aaa)报错了,原因是AAA 会向上一级父类Object类进行查找,看父类有没有这个方法,如果有,那么久调用父类的方法,如果没有就会提升报错。

现在修改aaa的类型为BBB,将 static void test( Object bbb ) 注释掉。

【java】多态_第6张图片
说明BBB 会向上一级父类AAA类进行查找和调用。

重写

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

public class Java15_Object {
    public static void main(String[] args) {

        Child15 child = new Child15();
        child.test();
    }
}
class Parent15 {

    void test() {
        System.out.println("parent test...");
    }
}
class Child15 extends Parent15 {

    void test() {
        super.test();
        System.out.println("child test...");
    }
}

这里的重写,并不意味着父类的方法被覆盖掉,只是在当前场合不使用。如果使用super关键字还是可以访问。

下面来看这串代码:

public class Java15_Object_1 {
    public static void main(String[] args) {

        CCC ddd = new DDD();
        System.out.println(ddd.sum());

    }
}
class CCC {
    int i = 10;
    int sum() {
        return i + 10;
    }

}
class DDD extends CCC {
    int i = 20;
    int sum() {
        return i + 20;
    }
}

这种情况下,我们的结果会是多少呢?
【java】多态_第7张图片
为什么呢?

一个对象能使用什么方法,取决于引用变量的类型
一个对象能使用什么属性,取决于引用变量的类型
一个对象的方法具体的使用(直接,间接)是需要看具体的对象的
一个对象的属性具体的使用是不需要看具体的对象的,属性在哪里声明在哪里使用

现在,我们对象的类型是CCC,那么是可以使用CCC中的sum,但具体的使用是DDD当中的sum,原因是new DDD()。

下面我们将DDD当中的sum进行注释

public class Java15_Object_1 {
    public static void main(String[] args) {

        CCC ddd = new DDD();
        System.out.println(ddd.sum());

    }
}
class CCC {
    int i = 10;
    int sum() {
        return i + 10;
    }

}
class DDD extends CCC {
    int i = 20;
//    int sum() {
//        return i + 20;
//    }
}

故而,这个时候的运行结果是20,使用的是CCC当中的sum。

我们再将代码进行更改:

public class Java15_Object_1 {
    public static void main(String[] args) {

        CCC ddd = new DDD();
        System.out.println(ddd.sum());
    }
}
class CCC {
    int i = 10;
    int sum() {
        return getI() + 10;
    }
    int getI() {
        return i;
    }
}
class DDD extends CCC {
    int i = 20;
//    int sum() {
//        return i + 20;
//    }
    int getI() {
        return i;
    }
}

【java】多态_第8张图片

你可能感兴趣的:(java,java,开发语言)