java 多态

重写

先来看以下代码:

// App.java
package com;
import com.A;
import com.B;
public class App {
    public static void main(String[] args) {
        // 下边调用:
        // (1)如果调用的类方法;那么左边的数据类型决定最后的输出结果。
        // (2)如果调用的是实例方法,这里边会存在一个子类重写父类的概念:  
        A a = new A();
        B b = new A(); // 父类的引用可以指向子类
        // 实例方法调用
        a.test(); // "A"
        b.test(); // "A"
        // 类方法调用
        a.t(); // "1"
        b.t(); // "2"
    }
}
// A.java
package com;
public class A extends B {
    @Override
    public void test() { System.out.println("A");}
    public static void t() { System.out.println("1");}
}
// B.java
package com;
public class B {
    @Override
    public void test() { System.out.println("B"); } 
    public static void t() { System.out.println("2"); }
}

上边在App.java中分别引入A.java 和 B.java
(1)如果调用的是类方法,那么左边的数据类型决定最后的输出结果, 所以上边输出的是 "1"和"2", 结果不同。

(2)如果调用的是类中的实例方法,那么这里边存在一个子类重写父类的概念:

子类会重写父类的test方法,上边加上了 @Override注解, 类似python中的装饰器,表示子类重写了父类的方法。

java 中子类继承基类,可以重写基类中的方法,一般我们会定义 @Override 注解,那么是否可以不加 @Override 呢?

显然也可以!

对于java中是否添加 @Override 的区别在哪里呢?

写的情况下,表示子类覆盖基类中的方法,基类中必须存在该方法,控制器类型(public,protected,返回值,参数列表)与子类方法完全一致,否则会报错(找不到被 @Override 的方法)

不写的情况下,JVM也会自动识别,如果不满足完全一致的条件,则被当作新方法定义

加@Override的好处有利于编译器帮忙检测错误。

重写的前提

(1)重写的前提:
        ·  只能是子类继承父类时,子类重写父类的方法;
        ·  方法名必须相同;
        · 
参数列表必须相同, 这点非常重要;
        ·  修饰符可以的范围可以扩大,也就是说,如果父类时私有方法,那么子类可以用public来                 把它继承过来( public > protected > default > private );
        ·  抛出的异常,范围可以被缩小,但不能被扩大;

(2)java 的重写只跟非静态方法有关系。

为什么需要重写

(1)父类的功能,子类不一定需要,或者不一定满足。

IDEA中重写的快捷键

  Alt + Insert  -> overide


多态

定义

同一方法,可以根据发送对象的不同,而采用多种不同的行为方法。一个对象的实际类型是确定的,但是可以指向对象的引用类型(一般指父类)有很多。

 

多态存在的条件

(1)存在继承关系;

(2)父类的引用指向子类的实例;

(3)子类重写父类的方法。

 

几个重点

(1)方法的多态,属性没有多态;

(2)存在的条件:继承关系,方法需要重写(子类和父类拥有相同的实例方法,方法体不一样,那么子类方法会重写父类的方法);

(3)父类的引用指向子类的对象;

(4)static类,final常量,private私有,不会重写,所以也不会存在多态的概念。

(5)多态是方法的多态,不是属性的多态。

(6)运行时,执行的方法,完全看左边的类型,由左边类型决定执行哪些方法。

 

// App.java 
import com.Person;
import com.Student;
public class App {
    public static void main(String[] args) {
        Student stu = new Student();
        Person per = new Student(); // 父类的引用指向了子类的实例(也就是子类实例类型也可以是父类类型,因为子类继承了父类)
        // per是父类类型,但是子类重写了父类的test方法,所以输出 "student"
        per.test(); // "student"
        // per调用a方法,a方法只有子类才有,所以需要把per父类类型转化为Student类型,才能调用a方法
        ((Student) per).a(); // "aaaa"
        // b方法只有父类有,所以输出 "bbbb"
        per.b(); // "bbbb"
    }
}
// Person.java 父类
package com;
public class Person {
    public void test() { // test方法被子类重写了!
        System.out.println("person");
    }
    public void b() {
        System.out.println("bbbb");
    }
}
// Student.java 子类
package com;
import com.Person;
public class Student extends Person{
    @Override // 重写父类test方法
    public void test() {
        System.out.println("student");
    }
    public void a() {
        System.out.println("aaaa");
    }
}

 

instanceof

判断一个对象是否是某个类的实例,前提条件:两者需要有继承关系。

import com.Person;
import com.Student; // Student类继承Person类
public class App {
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student instanceof Person); // true
        System.out.println(student instanceof Object); // true
    }
}

类型转化

向上转型

向下转型

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值