美文网首页
Java 面向对象-多态

Java 面向对象-多态

作者: ttlidx | 来源:发表于2020-03-18 09:47 被阅读0次

    1.多态概述

    什么是多态?

    多种状态,通一个对象在不同情况下表现出不同的状态或行为

    Java中实现多态的步骤

    ·要有继承(或实现)关系

    ·要有方法重写

    ·父类引用指向子类对象(is a 关系)

    例子:

    //定义父类Animal

    public class Animal {

        //成员变量

        //姓名

        private Stringname;

        //成员方法

        public void eat(){

            System.out.println("正在吃东西");

        }

        //构造方法

        //无参构造

        public Animal() {

        }

        //带参构造

        public Animal(String name) {

            this.name = name;

        }

        //公共访问方式:getXXX() ,setXXX()

        public void setName(String name) {

            this.name = name;

        }

        public String getName() {

            return name;

        }

    }

    //定义子类Dog

    public class Dogextends Animal{

        //需求:狗吃骨头,所以要优化父类中的eat()方法

        public void eat(){

            System.out.println(this.getName()+"正在吃骨头");

        }

    }

    //测试类

    public class Test {

    /*

            动物案例:

            已知父类Animal ,成员变量为:姓名 成员方法:eat()

            其有一子类Dog,请用该案例模拟多态

    */

        public static void main(String[] args) {

            //演示多态

            /*

                Java中实现多态的三个步骤           

                1.要有继承(或实现)关系           

                2.要有方法重写

                3.要有父类引用指向子类对象

            */

                //多态

            Animal an =new Dog();

            an.setName("哈士奇");

            an.eat();

        }

    }

    运行结果:

    多态关系中成员方法的使用

    需求:父类型变量作为参数时,可以接收任意子类对象

    分析:

    A:定义方法,参数类型为父类型Animal

    showAnimal(Animal animal)

    B:分别创建Dog类和Mouse类

    C:调用showAnimal方法演示效果

    //定义父类Animal

    public class Animal {

        //成员变量

        private Stringname;

        //成员方法

        public void eat() {

            System.out.println("吃饭");

        }

        //构造方法

        //无参构造

        public Animal() {

        }

        //带参构造

        public Animal(String name) {

            this.name = name;

        }

        //公共访问方式:getXXX() ,setXXX()

        public void setName(String name) {

            this.name = name;

        }

        public String getName() {

            return name;

        }

    }

    //定义子类Dog

    public class Dogextends Animal {

        //成员方法

        public void eat(){

            System.out.println(this.getName()+"吃骨头");

        }

    }

    //定义子类Mouse

    public class Mouseextends Animal{

        public void eat(){

            System.out.println(this.getName()+"吃奶酪");

        }

    }

    //测试类

    public class Test {

        public static void main(String[] args) {

        /*

                需求:

                定义方法,参数类型为父类型Animal  showAnimal(Animal animal)

                分别创建Dog类和Mouse类

                调用showAnimal方法演示效果

        */

            //用来测试Dog类和Mouse类

            Dog d =new Dog();

            d.setName("哈士奇");

            showAnimal(d);

            Mouse m =new Mouse();

            m.setName("Jerry");

            showAnimal(m);

            System.out.println("==============");

            //多态的作用

            Animal dog =new Dog();

            dog.setName("狗");

            Animal mouse =new Mouse();

            mouse.setName("老鼠");

            showAnimal(dog);

            showAnimal(mouse);

        }

        //传统做法

        //需求:在该类中定义showAnimal方法

        public static void showAnimal(Dog d){

            d.eat();

        }

        public static void showAnimal(Mouse m){

            m.eat();

        }

        //多态的做法

        public static void showAnimal(Animal an){

            an.eat();

        }

    }

    运行结果:

    多态关系中成员变量的使用

    需求:子父类中定义了同名的成员变量,如何调用

    分析

    A:子类中定义同名属性name并分别初始化值

    String name;

    B:在测试类中以多态的方式创建对象并打印name属性值:Animal animal = new Dog();

    C:在测试类中以普通方式创建对象并打印name属性值:Dog dog = new Dog();

    //定义父类Animal

    public class Animal {

        Stringname ="Animal";

    }

    //定义子类Dog

    public class Dogextends Animal{

        Stringname ="Dog";

    }

    //测试类

    public class Test {

    public static void main(String[] args) {

    Animal an =new Dog();

    System.out.println(an.name);//Animal

            Dog dog =new Dog();

    System.out.println(dog.name);//Dog

        }

    }

    运行结果:

    结论:

    多态关系中成员变量是不能重写

    2.多态的好处和弊端

    多态的好处

    ·可维护性:基于继承关系,只需要维护父类代码,提高了代码的复用性,大大大降低了维护程序的工作量

    ·可拓展性:把不同的子类对象都当做父类看待,屏蔽了不同子类对象间的差异,做出通用的代码,以适应不同的需求

    多态的弊端

    不能使用子类特有成员

    解决方案:

    类型转换

    当需要子类特有功能时,需要进行类型转换

    向上转型(自动型转换)

    -子类型转换成父类型

    Animal animal = new Dog();

    向下转型(强制转换)

    -父类型转换成子类型

    Dog dog =(Dog)animal;

    注意事项

    ·只能在继承层次捏进行转换(ClassCastException)

    ·将父类对象转换成子类型之前,使用instanceof进行检查

    if(an.instanceof Dog){ //判断an是否时Dog类型的对象

    //是Dog类型对象

    Dog dog =(Dog)animal;

    }

    4.抽象类的特点

    抽象类的特点

    1.修饰符:必须用abstract关键字修饰

    -修饰符 abstract class 类名{}

    -修饰符 abstract 返回值类型 方法名();

    2.抽象类不能被实例化,只能创建子类对象

    3.抽象类的子类只有两个选择

    -重写父类所有抽象方法

    -定义成抽象类

    抽象类的成员特点

    1.成员变量:

    可以有普通的成员方法

    也可以有成员常量(final)

    2.成员方法:

    可以有普通方法,也可以有抽象方法

    抽象类不一定有抽象方法,有抽象方法的类一定是抽象类(或接口)

    3.构造方法:

    像普通类一样有构造方法

    案例:

    需求:开发团队中有程序员和经理两种角色,他们都有姓名、工资、工号等属性,都有工作行为,经理还要奖金属性。请使用继承思想设计出上述需求中的类,并分别创建对象使用

    分析

    A:经理和程序员都是员工,把他们的共同的属性和行为定义子在父类Employee中,由于并不明确工作的具体内容,所以父类中工作的方法定义成抽象方法;

    name ,salary, id , work()

    B:定义经理类Manager,继承Employee,属性和行为:bonus;work();

    C:定义程序员类Coder,继承Employee,属性和行为:work();

    D:在测试类中分别创建对象并使用

    //定义一个父类 抽象类Employee

    public abstract class Employee {

        //成员变量

        //姓名

        private Stringname;

        //工号

        private Stringid;

        //工资

        private double salary;

        //成员方法 抽象方法

        //工作

        public abstract void work();

        //公共访问方式

        public void setName(String name) {

            this.name = name;

        }

        public void setId(String id) {

            this.id = id;

        }

        public void setSalary(double salary) {

            this.salary = salary;

        }

        public String getName() {

            return name;

    }

        public String getId() {

            return id;

        }

        public double getSalary() {

            return salary;

        }

        //构造方法

        //无参构造

        public Employee() {

        }

        //全参构造

        public Employee(String name, String id,double salary) {

            this.name = name;

            this.id = id;

            this.salary = salary;

        }

    }

    //定义一个子类 Manager 经理类继承父类Employee

    public class Managerextends Employee{

        //成员变量

        //奖金

        private double bonus;

        //实现抽象方法

        public void work() {

            System.out.println(this.getName()+"正在监督");

        }

        //公共访问方式

        public void setBonus(double bonus) {

            this.bonus = bonus;

        }

        public double getBonus() {

            return bonus;

        }

        //构造方法

        public Manager() {

        }

        public Manager(String name, String id,double salary,double bonus) {

            super(name, id, salary);

            this.bonus = bonus;

        }

    }

    //定义一个子类 Coder 程序员类 继承抽象类Employee

    public class Coderextends Employee{

        //实现抽象方法

        public void work() {

            System.out.println(this.getName()+"正在写代码");

        }

        //构造方法

        public Coder() {

        }

        public Coder(String name, String id,double salary) {

            super(name, id, salary);

        }

    }

    public class Test {

    public static void main(String[] args) {

            //创建经理对象

            Employee manager =new Manager();

            manager.setName("张三");

            manager.work();

            //创建程序员类

            Employee coder =new Coder();

            coder.setName("李四");

            coder.work();

        }

    }

    运行结果:

    5.final关键字

    final的概念

    最终的、最后的

    final 的作用

    1.修饰类:该类不能被继承

    String,System

    2.修饰方法:该方法不能被重写

    不能与abstract共存

    3.修饰变量:最终变量,即常量,只能赋值异常

    不建议修饰引用类型数据,因为仍然可以通过引用修改对象的内部数据,意义不大

    6.static关键字

    static 的概念

    静态的

    static 的作用

    用于修饰类的成员:

    1.成员变量:类变量

    2.成员方法:类方法

    调用方式:

    类名.成员变量;

    类名.成员方法(参数);

    static 修饰成员变量

    特点:被本类所有对象共享

    -随意修改静态变量的值是有风险的,为了降低风险,可以同时用final关键字修饰,即公有静态常量(注意命名的变化)

    static 修饰成员方法

    1.静态方法

    -静态方法中没有对象this,所以不能访问非静态成员

    2.静态方法的使用场景

    -只需要访问静态成员

    -不需要访问对象状态,所需参数都由参数列表显示提供

    7.接口概述

    接口的概念

    接口技术用于描述具有什么功能,但并不给出具体实现,类要遵守从接口描述的统一规则进行定义,所以,接口时对外提供的一组规则、标准

    接口的定义

    ·定义接口使用关键字 interface

    interface 接口名{}

    ·类和接口是实现关系,用implements表示

    class 类名 implements 接口名

    接口的特点

    接口创建对象的特点:

    1.接口不能实例化

    通过多态的方式实例化子类对象

    2.接口的子类(实现类)

    可以是抽象类,也可以是普通类

    如果是抽象类,不要重写接口的方法,如果是普通类,必须重写所有接口方法

    接口继承关系的特点:

    1.接口与接口之间的关系

    继承关系,可以多继承,格式

    接口 extends 接口1,接口2,接口3.....

    2.继承和实现的区别

    继承体系的是”is a“的关系,父类中定义共性内容

    实现体系的是”like a “的关系,接口中定义扩展功能

    8.接口成员的特点

    接口成员变量的特点

    接口没有成员变量,只有公有的、静态的常量

    public static final 常量名 = 常量值;

    接口成员方法的特点

    JDK7之前,公有的、抽象方法:

    public abstract 返回值 方法名()

    JDK8之后,可以有默认方法和静态方法:

    public default 返回值类型 方法名(){}

    JDK9之后,可以有私有方法:

    private 返回值类型 方法名(){}

    接口构造方法的特点

    接口不能够实例化,也没有需要初始化的成员

    所以接口没有构造方法

    相关文章

      网友评论

          本文标题:Java 面向对象-多态

          本文链接:https://www.haomeiwen.com/subject/ppihyctx.html