Java_Day16(多态、抽象、接口)

Java_Day16(多态、抽象、接口)

多态

  • 什么是多态:
    • 同一个对象,在不同时刻表现出来的不同形态.
    • 我们可以说猫是猫:猫 cat = new 猫();
    • 我们也可以说猫是动物:动物 animal = new 猫();
    • 这里猫在不同的时刻表现出来了不同的形态,这就是多态
  • 多态的前提:
    • 要有继承/实现关系
    • 要有方法的重写
    • 要有父类引用指向子类对象
  • 多态的特点:
    • 需要有继承关系
    • 方法重写
    • 父类引用执行子类对象
    public static void main(String[] args) {
//        Animal a = new Animal();
//        Cat c = new Cat();
        // 父类引用指向子类对象
        Animal cat = new Cat();
        Animal dog = new Dog();
        System.out.println(cat.leg);//2
        System.out.println(dog.leg);//2
        cat.eat();//猫吃鱼
        dog.eat();// 狗吃骨头
    }
  • 多态访问成员变量的特点:
    • 在多态中,如果在子类和父类中出现同名的成员变量 则使用的是父类的成员变量
    • 成员变量的访问: 编译看左边,运行看左边
  • 多态访问成员方法的特点:
    • 在多态中,如果子类重写了父类的方法,则使用的是子类的方法
    • 成员方法的访问:编译看左边,运行看右边

若编译时类型和运行时类型不一致, 就出现了对象的多态性(Polymorphism)
多态情况下成员方法, “看左边” : 看的是父类的引用(父类中不具备子类特有的方法)
“看右边” : 看的是子类的对象(实际运行的是子类重写父类的方法)
成员变量: 不具备多态性,只看引用变量所声明的类。

使用多态来调用方法只能调用子类和父类都有的方法(必须存在方法的重写)。而不能调用子类 特有的方法

多态的好处和弊端

好处
  • 提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
弊端
  • 不能使用子类的特有成员
public class Person {
    // 人要饲养一只动物  使用父类作为参数  当引用的时候 传入具体所指的真实 子类
    public void  siyang(Animal  animal){
        animal.eat();
    }
}
    public static void main(String[] args) {
//        Animal a = new Animal();
//        Cat c = new Cat();
        // 父类引用指向子类对象
        Animal cat = new Cat();
        Animal dog = new Dog();
        System.out.println(cat.leg);//2
        System.out.println(dog.leg);//2
        cat.eat();//猫吃鱼
        dog.eat();// 狗吃骨头
        Person person = new Person();
        person.siyang(cat);// 传入真实的所引用的对象
        person.siyang(dog);//传入真实 的所引用的对象
    }


对于子类特有成员的访问

// 只有 真实的类型对象 才能调用当前子类中特有的 方法
Cat c = new Cat();
Dog d = new Dog();
c.play();
d.work();
// 进行类型转换
Cat  cc = (Cat) cat;
cc.play();
Dog dd = (Dog) dog;
dd.work();

  • 类型转换:
    • 类型提升:将父类型的引用执行子类对象,由小到大,进行自动转换(多态)
    • 造型 :将父类型的引用对象转换为子类型的对象由大到小,强制转换
  • 从子类到父类的类型转换可以自动进行
  • 从父类到子类的类型转换必须通过造型(强制类型转换)实现
  • 无继承关系的引用类型间的转换是非法的

在类型转换中 (造型)

Dog dog1 = (Dog) cat;
dog1.work();

在这里插入图片描述
类型转换异常

解决方法:
使用instanceof 判断一个引用是否是某一个类的实例对象

if(cat instanceof  Dog){
    Dog dog1 = (Dog) cat;
    dog1.work();
}else{
    System.out.println("类型不匹配");
}

方法的重载与重写

  • 重载,是指允许存在多个同名方法,而这些方法的参数不同。 编译器根据方法不同的参数表, 对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。 它们的调用地址在编译期就绑定了。 Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。所以: 对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定” ;
  • 而对于多态,只有等到方法调用的那一刻, 解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定

抽象 abstract

Abstract 可以修饰类 修饰类的时候 类就称为抽象类
修饰方法的时候 就称为抽象方法

package cn.lanqiao.abs;
// 抽象类
public abstract class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    // 抽象方法
    public abstract   void  work();
}


组成

  1. 成员变量
  2. 成员方法
  3. 构造方法
  4. 构造代码块
  5. 抽象方法
  6. 常量
  7. 类变量
  8. 静态代码块

特点

  • 抽象类不能被实例化(不能创建对象)
  • 抽象类是用来被继承的
  • 抽象类的子类必须去重写抽象类中的抽象方法
    • 要么全部重写
    • 只是重写部分则子类也必须是抽象的
  • 抽象类中不一定有抽象方法
  • 含有抽象方法的必须是抽象类
package cn.lanqiao.abs;

import java.util.zip.ZipError;

public class Student  extends Person {

    @Override
    public void work() {
        System.out.println("努力敲代码,学习Java技术,冲刺年薪百万....");
    }
}


package cn.lanqiao.abs;

public class Worker extends Person{
    @Override
    public void work() {
        System.out.println("努力工作,赚钱还房贷.....");
    }
}


package cn.lanqiao.abs;

public class PersonTest {
    public static void main(String[] args) {
        // 抽象类不能被实例化
       // Person p = new Person();
        Person person1 = new Student();
        person1.work();
        Person person2 =new Worker();
        person2.work();
    }
}

意义

抽象类中构造方法存在的意义:

  • 对于抽象类我们自己不能在外部使用他的构造方法创建对象,但是jvm可以。
  • 在创建子类对象的时候 jvm会创建一个父类的隐含对象,便于我们对于抽象类的成员的访问

模板方法设计模式(TemplateMethod)

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

解决的问题:

  • 当功能内部一部分实现是确定的, 一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
  • 换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。
package cn.lanqiao.tempalte;

public abstract class TemplateMethod {
    //计算代码的执行时间
  //  public static long currentTimeMillis()
    public  long  getCodeTime(){
        // 获取代码开始执行的时间
        long begin = System.currentTimeMillis();
        //开始执行代码
        code();
        //代码执行结束  获取结束之后的 时间
        long end = System.currentTimeMillis();
        return  end - begin;//毫秒
    }

    public abstract void  code();
}

package cn.lanqiao.tempalte;

public class TemplateTest extends  TemplateMethod {
    @Override
    public void code() {
        int  sum = 0;
        for(int i = 0 ; i < 10000;i++){
            sum += i;
        }
        System.out.println(sum);
    }

    public static void main(String[] args) {
        TemplateMethod tm = new TemplateTest();
        long time =  tm.getCodeTime();
        System.out.println(time);
    }
}


public static long currentTimeMillis()
在1970年1月1日UTC之间的当前时间和午夜之间的差异,以毫秒为单位

接口

• 接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用
• Java中的接口更多的体现在对行为的抽象
• 接口的本质是契约,规范,就像我们人间的法律一样。制定好后大家都遵守。

接口中的定义:

  1. 常量 public static final (可不写) 默认就是这样的
  2. 方法 必须是抽象方法 public abstract(修饰符可不写)方法默认就是 抽象的
  3. 没有构造方法
  4. 不能存在代码块
  5. 不能存在变量

接口的特点:

  1. 接口不能被实例化
  2. 接口是用来被实现的 实现接口的类 必须实现接口的抽象方法
  3. 一个类可以实现多个接口
  4. 一个类在继承的同时也可以实现就接口
  5. 接口可以继承接口且只能继承接口
  6. 接口可以多继承

实现类要么实现所有的方法 要么是抽象类(实现接口的部分抽象方法)

public interface JDBCDao {
     int  num = 10;

     void insert();
     void delete();
     void update();
     void select();
}


package cn.lanqiao.inter;

public  class JDBCDaoImpl implements JDBCDao{


    @Override
    public void insert() {
        System.out.println("插入一条数据");
    }

    @Override
    public void delete() {
        System.out.println("删除一条数据");
    }

    @Override
    public void update() {
        System.out.println("修改一条数据");
    }

    @Override
    public void select() {
        System.out.println("查询数据");
    }


}



public class JDBCTest {
    public static void main(String[] args) {
        JDBCDao dao = new JDBCDaoImpl();// 这种就称为接口的多态
        dao.insert();
        dao.delete();
        dao.update();
        dao.select();
    }
}

所以在实际的使用中,接口往往只是方法的规范,对于接口中的常量基本不用

类、接口、多态

多态的分类

  1. 具体的多态
  2. 抽象类的多态
  3. 接口的多态

关系

  • 类和类的关系
    • 继承关系,只能单继承,但是可以多层继承
  • 类和接口的关系
    • 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
  • 接口和接口的关系
    • 继承关系,可以单继承,也可以多继承

抽象类和接口的区别

No.区别点抽象类接口
1定义包含抽象方法的类主要是抽象方法和全局常量的集合
2组成构造方法、抽象方法、普通方法、常量、变量常量、抽象方法、
3使用子类继承抽象类(extends)子类实现接口(implements)
4关系抽象类可以实现多个接口接口不能继承抽象类,但允许继承多个接口
5常见设计模式模板方法 简单工厂、工厂方法、代理模式
6对象都通过对象的多态性产生实例化对象
7局限抽象类有单继承的局限接口没有此局限
8实际作为一个模板是作为一个标准或是表示一种能力
9选择如果抽象类和接口都可以使用的话,优先使用接口,因为避免单继承的局限
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值