09-java多态,抽象类,接口

多态的概述及其代码体现
多态(polymorphic)的概述
  • 事物存在的多种形态
多态的前提
  • 要有继承关系
  • 要有方法重写
  • 要有父类引用指向子类对象
class Demo1_Polimorphic{
    public static void main(String[] args){
        Cat c =new Cat();
        c.eat();

        Animal a=new Cat();
        a.eat();
    }
}
class Animal {
    public void eat(){
        System.out.println("动物吃饭");
    }
}
class Cat extends Animal{
    public void eat(){
        System.print("猫吃鱼");
    }
}
多态中的成员访问特点
成员变量

==编译看左边(父类),运行看左边(父类)==

class Demo2_Polymorphic {
    public static void main(String[] args){
        Father f=new Son();
        System.out.println(f.num);
    }
}
class Father{
    int num=10;
}
class Son extends Father{
    int num=20;
}

多态成员变量访问方式

成员方法

==编译看左边(父类),运行看右边(子类)(动态绑定)==
多态成员方法访问方式

静态成员方法

==编译看左边(父类),运行看右边(子类)==
(静态和类相关,关不上重写,所以访问还是看左边)
只有非静态的成员方法编译看左边,运行看右边

超人的故事
class Demo3_SuperMan{
    public static void main(String[] args){
        Person p=new SuperMan();
        System.out.println(p.name);
        p.谈生意();
        SuperMan sm=(SuperMan)p;      //向下转型
        sm.fly();
    }
}
class Person {
    String name = "John";
    public void 谈生意(){
        System.out.println("谈生意");
    }
}
class SuperMan extends Person {
    String name="superMan";
    public void 谈生意(){
        System.out.println("谈几个亿的大单子");
    }
    public void fly(){
        System.out.println("飞出去救人");
    }
}
多态向上转型和向下转型
  • Person p= new SuperMan(); 向上转型
  • SuperMan sm=(SuperMan)p; 向下转型
    Superman
多态的好处和弊端
多态的好处
  • 提高了代码的维护性(继承保证)
  • 提高了代码的扩展性(多态保证)
public static void main(String[] args){

    //Cat c1=new Cat();
    //c1.eat();

    method(new cat());
    method(new cat());

    //Animal a=new Cat();   开发的是很少在创建对象的时候用父类引用指向子类对象,直接创建子类对象
}    
//Cat c=new Dog(); 狗是一只猫,这是错误的
/*public static void method(Cat c){
    c.eat();
}
public static void method(Dog d){
    d.eat();
}*/
//如果把狗强转成猫就会出现类型转换异常ClassCastException

public static void method(Animal a){  
//当做参数的时候用多态最好,因为扩展性强
// 关键字instanceof 判断前边的引用是否是后边的数据类型
    if(a instanceof Cat){
        Cat c=(Cat)a;
        c.eat();
        c.catchMouse();
    }else if(a intanceof Dog){
        Dog d=(Dog)a;
        d.eat();
        d.lookHome();
    }else{
        a.eat();
    }
}
class Animal{
    public void eat(){
        System.out.print("动物吃饭");
    }
}

class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}

class Dog extends Animal{
    public void eat(){
        System.out.println("狗吃肉");
    }
    public void lookdog(){
        System.out.println("看门");
    }
}

==开发的时候很少在创建对象的时候用父类引用指向子类对象,直接创建子类对象更方便,可以使用子类对象中的特有属性和行为==

==当做参数的时候用多态最好,因为扩展性强==

如果把狗强转成猫就会出现类型转换异常,ClassCastException

案例演示
  • 多态的好处
  • 可以当做形式参数,可以接收任意子类对象
多态的弊端
  • 不能使用子类的特有属性和行为
案例演示
关键字 instanceof 判断前边的引用是否是后边的数据类型
public static void method(Animal a){
    if(a instanceof Cat){
        Cat c=(Cat)a;
        c.eat();
        c.catchMouse();
    }else if(a instanceof Dog){
        Dog d=(Dog)a;
        d.eat();
        d.lookHome();
    }else{
        a.eat();
    }
}
抽象类的概述及其特点
  • 抽象类概述
抽象类的特点
class Demo1_Abstract{
    public static void main(String[] args){
        /*Animal a=new Animal();  
        错误Animal是抽象的,无法实例化*/
        Animal a=new Cat();
        a.eat();
    }
}
abstract class Animal{
    public class Animal{
        public abstract void eat();
    }
}
抽象类和抽象方法必须用abstract关键字修饰
- abstract class 类名{}
- public abstract void eat();
abstract class Animal{
    public abstract void eat();
}
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或接口;
抽象类不能实例化,那么抽象类如何应用?
  • 按照多态的方式,由具体子类实例化.其实这也是一种多态,抽象类多态
抽象类的子类
  • 要么是抽象类
  • 要么重写抽象类中所有的抽象方法
抽象类成员的特点
  • 成员变量: 既可以是变量,又可以是常量.abstract不可以修饰成员变量
  • 构造方法: 有
    • 用于子类访问父类数据的初始化
  • 案例演示
  • 抽象类的成员方法特性
    • 抽象方法 强制要求子类做事情
    • 非抽象方法 子类继承的事情,提高代码复用性
  • 猫狗案例
class Test1_Animal{
    public static void main(String[] args){
        Cat c=new Cat("加菲",8);
        System.out.println(c.getName()+"..."+
        c.getAge);
        c.eat();
        c.catchMouse();

        Dog d=new Dog("八公",30);
        System.out.println(d.getName()+"..."+
        d.getAge);
        d.eat();
        d.lookHome();
    }
}
/*
案例演示
具体事务: 猫 狗
共    性: 姓名 年龄 吃饭
猫的特性: 抓老鼠
狗的特性: 看家
*/
Abstract class Animal{
    private String name;    //姓名
    private int age;        //年龄

    public Animal(){}       //空参
    public Animal(String name,int age){
    //有参
        this.name=name;
        this.age=age;       
    }
    public void setName(String name){
        this.name=name;     //设置姓名
    }
    public String getName(){
        return name;        //获取姓名
    }
    public void setAge(int age){
        this.age=age;       //设置年龄
    }
    public int getAge(){
        return age;         //获取年龄
    }

    public abstract void eat();  //吃饭
}
class Cat extends Animal{

    public Cat(){}       //空参
    public Cat(String name,int age){
        super(name,age);     
    }
    public abstract void eat(){
        System.out.println("猫吃鱼");
    }
    public void catchNouse(){
        System.out.prinrln("抓老鼠");
    }
}

class Dog extends Animal{

    public Dog(){}       //空参
    public Dog(String name,int age){
        super(name,age);     
    }
    public abstract void eat(){
        System.out.println("狗吃肉");
    }
    public void lookHome(){
        System.out.prinrln("看家");
    }
}
葵花宝典
class Demo3_葵花宝典{
    public static void main(String[] args){
        岳不群 小岳子=new 岳不群();
        小岳子.自宫();
    }
}

abstract class 葵花宝典{
    public abstract void 自宫();
}

class 岳不群 extends 葵花宝典{
    public void 自宫(){
        System.out.println("牙签");
    }
}

class 林平之 extends 葵花宝典{
    public void 自宫(){
        System.out.println("用指甲刀");
    }
}

class 东方不败 extends 葵花宝典{
    public void 自宫(){
        System.out.println("用锤子,不忍直视");
    }
}
面试题
  • 一个抽象类如果没有抽象方法,可不可以定义为抽象类?有什么意义?
    • 可以,这么做的目的只有一个,就是不让其他类创建本类对象,交给子类完成
  • abstract不能和哪些关键字共存
    • static 被abstract修饰的方法没有方法体,被static修饰的可以用类名.调用,但类名.调用抽象方法是没有意义的
    • final 被abstract修饰的方法强制子类重写,final不让子类重写,而这矛盾
    • private abstract修饰是为了让子类看到并重写,private不让子类访问,所以他俩是矛盾的
接口的概述及其特点
接口的概述
  • 从狭义角度讲就是java中的interface
  • 从广义角度讲对外提供规则的都是接口
接口用关键字interface表示
  • interface 接口名{}
类实现接口用implements表示
  • class 类名 implements 接口名{}
接口不能实例化
  • 如何实例化?按照多态的方式来实例化
接口的子类
  • 可以是抽象类,但意义不大
  • 可以使具体类,要重写接口中所有的抽象方法
class Demo1_Interface{
    public static void main(String[] args){
        //Inter i=new Inter(); 
        接口不能被实例化,因为调用抽象方法无意义
        Inter i=new Demo();
        i.print();
    }
}

interface Inter{
    public abstract void print();
}
class Demo implement Inter{
    public void print(){
        System.out.println("print");
    }
}
接口成员特点
成员变量
  • 只能是常量,并且是静态的公共的
interface Inter{
    (public static final) int num=10;
}
class Demo implements Inter{
    public void print(){
        num=20;                         //错误
        System.out.println(num);
    }
}
  • 默认修饰符: public static final
  • 建议自己手动给出
构造方法
  • 接口没有构造方法
成员方法
  • 只能是抽象方法
  • 默认修饰符:public abstract
  • 建议手动给出
类与类,类与接口,接口与接口之间的关系
  • 类与类: 继承关系,只能单继承,可以多层继承
  • 类与接口: 实现关系可以单实现,也可以多实现;并且还可以继承一个类的同时实现多个接口
  • 接口与接口: 继承关系,可以单继承,也可以多继承
抽象类和接口的区别
成员区别
  • 抽象类
    • 成员变量:可以变量,也可以常量
    • 构造方法:有
    • 成员方法:可以抽象,也可以非抽象
  • 接口
    • 成员变量:只可以市常量
    • 构造方法:无
    • 成员方法:只可以抽象
关系区别
  • 类与类:继承,单继承
  • 类与接口:单实现,多实现
  • 接口与接口:继承
class Demo3_Interface{
    public static void main(String[] args){
        System.out.println("Hello World");
    }
}

interface InterA{
    public abstract void printA()
}

interface InterB{
    public abstract void printB()
}
//class Demo implements InterA,implements InterB{}
//这么做不允许,是非法的
class Demo implements InterA,InterB{
    public void printA(){
        System.out.println("printA");
    }
    public void printB(){
    System.out.println("printB");
    }
}

//interface InterC implements InterB{}
//错误 接口不能继承实现接口
interface InterC extends InterB,InterA{}
设计理念区别
  • 抽象类 被继承体现的是:”is a”的关系,抽象类中定义的是该集成体系的共性功能
  • 接口 被实现体现的是:”like a”的关系,接口中定义的是该继承体系的扩展功能
抽象类猫狗案例
class Test1_Animal{
    public static void main(String[] args){
        Cat c=new Cat("加菲",8);
        c.eat();
        c.sleep();

        JumpCat jc=new JumpCat("跳高猫",3);
        jc.eat();
        jc.sleep();
        jc.jump();
    }
}
/*
案例演示
动物类:姓名 年龄 吃饭 睡觉
猫和狗
动物培训接口:调高
*/
abstract class Animal{
    private String name;    //姓名
    private int age;        //年龄

    public Animal(){}       //空参构造

    public Animal(String name,int age){
        //有参构造
        this.name=name;
        this.age=age;
    }

    public void setName(String name){
        this.name=name;     //设置姓名
    }
    public string getName(){
        return name;        //获取姓名
    }
    public void setAge(int age){
        this.age=age;       //设置年龄
    }
    public int getAge(){
        return age;         //获取年龄
    }

    public abstract void eat();

    public abstract void sleep();
}

interface Jumping{
    public void jump();     //跳高的接口
}

class Cat extends Animal {
    public Cat(){}          //空参

    public Cat(String name,int age){
        super(name,age);    //有参
    }

    public void eat(){
        System.out.println("猫吃鱼");
    }

    public void sleep(){
        System.out.println("侧着睡");
    }
}

class JumpCat extends Cat implements Jumping{

    public Animal(){}       //空参构造

    public Animal(String name,int age){
        super(name,age)
    }
    public void jump(){
        System.out.println("猫跳高");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值