zoukankan      html  css  js  c++  java
  • Java 面向对象_多态

    多态图解

    代码中体现多态性

    父类名称 对象名 = new 子类名称();

    or

    接口名称 对象名 = new 实现类名称();

    // 父类
    public class Father {
        public void method(){
            System.out.println("parent class method call");
        }
    
        public void methodFather(){
            System.out.println("parent class specific method");  // 父类特有方法
        }
    }
    
    // 子类
    public class Son extends Father{
        @Override
        public void method(){
            System.out.println("sub class method call");
        }
    }
    
    public class DemoMulti{
        public static void main(String[] args){
            // 使用多态写法,左侧父类的引用,指向了右侧子类的对象(类似于一只狗被当做了一只动物)
            Father son = new Son();
            son.method();  // sub class method call
            son.methodFather();  // parent class specific method
        }
    }

    多态中成员变量的特点

    访问成员变量的两种方式:

    1. 直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找

    2. 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找

      指的是 Father f = new Son(); 中的等号

    口诀:编译看右边,运行还看右边 (成员变量的话, 运行是看左边?)

    // 父类
    public class Father {
        String name = "Father";
        
        public String showName() {
            return this.name;
        }
    }
    
    // 子类
    public class Son extends Father{
        String name = "Son";
        int age = 20;
        
        @Override
        public String showName() {  
            return this.name;
        }
    }
    
    public class DemoMulti{
        public static void main(String[] args){
            // 使用多态写法,左侧父类的引用,指向了右侧子类的对象(类似于一只狗被当做了一只动物)
            Father f = new Son();
            System.out.println(f.name);  // Father
            // System.out.println(son.age);  // 错误写法
            
            // 子类没有覆盖重写,就是父:Father
            // 子类有覆盖重写,就是子:Son
            System.out.println(f.showName());  // Son
        }
    }

    多态中成员方法的特点

    看 new 的是谁,就优先用谁,没有则向上找

    口诀:编译看左边,运行看右边

    // 父类
    public class Father {
        public void method(){
            System.out.println("parent class method call");
        }
    ​
        public void methodFather(){
            System.out.println("parent class specific method");  // 父类特有方法
        }
    }
    ​
    // 子类
    public class Son extends Father{
        @Override
        public void method(){
            System.out.println("sub class method call");
        }
        
        public void methodSon(){
            System.out.println("son class specific method");  // 子类特有方法
        }
    }
    ​
    public class DemoMulti{
        public static void main(String[] args){
            Father f = new Son();  // 多态
            f.method();  // 父子都有,优先用子
            f.emthodFather();  // 子类没有,父类有,向上找到父类
            
            // f.methodSon();  // 错误写法
        }
    }

    对象转型图解

    对象的向上转型

    public abstract class Animal {
        public abstract void eat();
    }
    ​
    public class Cat extends Animal{
        @Override
        public void eat(){
            System.out.println("cat eat fish");
        }
    }
    ​
    public class DemoTransition {
        public static void main(String[] args) {
            // 向上转型,就是父类引用 指向 子类对象
            Animal cat = new Cat();
            cat.eat();  // cat eat fish
        }
    }

    对象的向下转型

    向上转型有一个弊端:对象一旦向上转型为父类,那么就无法调用子类原本特有的内容

    public abstract class Animal {
        public abstract void eat();
    }
    ​
    public class Cat extends Animal{
        @Override
        public void eat(){
            System.out.println("cat eat fish");
        }
        
        public void catchMouse(){
            System.out.println("cat catches mouse");
        }
    }
    ​
    public class DemoTransition {
        public static void main(String[] args) {
            // 对象的向上转型,就是父类引用 指向 子类对象
            Animal cat = new Cat();
            cat.eat();  // cat eat fish
    // cat.catchMouse();  // 错误写法
            // 向下转型,进行还原
            Cat transitionCat = (Cat) cat;
            transitionCat.catchMouse(); // cat catches mouse
        }
    }

    instanceof 关键字进行类型判断(为了避免向下转型异常:ClassCastException)

    if (cat instanceof Cat){
        Cat transitionCat = (Cat) cat;
    }

     

    综合案例(笔记本USB接口)

     

    // 定义 USB 接口

    public interface USB {
        void enable();
        void disable();
    }

    // 鼠标实现类

    // 鼠标是一种 USB 设备
    public class Mouse implements USB {
        String name = "mouse";
    
        @Override
        public void enable() {
            System.out.println("enable " + this.name);
        }
    
        @Override
        public void disable() {
            System.out.println("disable " + this.name);
        }
    
        public void click(){
            System.out.println("click on the event");
        }
    }

    // 键盘实现类

    // 键盘也是一种 USB 设备
    public class KeyBoard implements USB {
        String name = "key board";
    
        @Override
        public void enable() {
            System.out.println("enable " + this.name);
        }
    
        @Override
        public void disable() {
            System.out.println("disable " + this.name);
        }
    
        public void tap(){
            System.out.println("tap on a event");
        }
    }

    // 电脑类

    public class MacBookPro {
        public void powerOn() {
            System.out.println("powerOn");
        }
    
        public void powerOff() {
            System.out.println("powerOff");
        }
    
        // 使用 USB 设备的方法,使用接口作为方法的参数
        public void useDevice(USB usb) {
            usb.enable();
            if (usb instanceof Mouse){
                // 向下转型
                Mouse mouse = (Mouse) usb;
                mouse.click();
            } else if (usb instanceof KeyBoard){
                KeyBoard keyBoard = (KeyBoard) usb;
                keyBoard.tap();
            }
            usb.disable();
        }
    }

    // main()

    public class DemoCase {
        public static void main(String[] args) {
            MacBookPro book = new MacBookPro();
    
            USB mouse = new Mouse();  // 多态写法,向上转型
            KeyBoard keyBoard = new KeyBoard();  // 自动发生了向上转型
    
            book.powerOn();  // powerOn
            book.useDevice(mouse);  // enable mouse, click on the event, disable mouse
            // 也可以直接传匿名对象 new KeyBoard()
            book.useDevice(keyBoard);  // enable key board, tap on a event, disable key board
            book.powerOff();  // powerOff
        }
    }

    # 参考廖雪峰教程

    Java的方法调用总是作用于运行期对象的实际类型,这种行为称为多态;

    public class Main {
        public static void main(String[] args) {
            // 给一个有普通收入、工资收入和享受国务院特殊津贴的小伙伴算税:
            Income[] incomes = new Income[] {
                new Income(3000),
                new Salary(7500),
                new StateCouncilSpecialAllowance(15000)
            };
            System.out.println(totalTax(incomes));
        }
    
        public static double totalTax(Income... incomes) {
            double total = 0;
            for (Income income: incomes) {
                total = total + income.getTax();
            }
            return total;
        }
    }
    
    class Income {
        protected double income;
    
        public Income(double income) {
            this.income = income;
        }
    
        public double getTax() {
            return income * 0.1; // 税率10%
        }
    }
    
    class Salary extends Income {
        public Salary(double income) {
            super(income);
        }
    
        @Override
        public double getTax() {
            if (income <= 5000) {
                return 0;
            }
            return (income - 5000) * 0.2;
        }
    }
    
    class StateCouncilSpecialAllowance extends Income {
        public StateCouncilSpecialAllowance(double income) {
            super(income);
        }
    
        @Override
        public double getTax() {
            return 0;
        }
    }

    ending ~ 

    每天都要遇到更好的自己.
  • 相关阅读:
    关于《哈利波特》书的购买方案
    你的灯亮着吗读后感三
    jmeter做接口测试
    jmeter的分布式部署
    JMeter的定时器
    我的功能测试用例是怎么写
    常见的功能测试检查点
    测试用例概论
    敏捷开发与迭代开发
    软件测试模型
  • 原文地址:https://www.cnblogs.com/kaichenkai/p/11718633.html
Copyright © 2011-2022 走看看