Java 面向对象-多态

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 返回值类型 方法名(){}

接口构造方法的特点

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

所以接口没有构造方法

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容