java day09 多态性、接口、修饰符(final、abstract)、向上转型、向下转型

1、多态性

1.1 概念

概念:父类引用指向子类对象,从而产生多种形态。

  • 父类对象指向子类对象
    父类类型 父类对象 = new 子类类型();
  • 接口对象指向实现类对象
    接口类型 接口对象 = new 实现类类型();
  • 约束父类对象只能调用子类从父类中继承的方法或者重写的方法
  • 在方法的参数中,可以接受参数类型对应的对象,还可以接受其对应的子类对象

开闭原则

  • open:对新增的代码持开放状态
  • close:对内部修改的代码持关闭状态

创建Animal.java

public class Animal {
    public void test01(){
        System.out.println("父类的方法1");
    }
    public void test02(){
        System.out.println("父类的方法2");
    }
}

创建Cat.java

public class Cat extends Animal {
    @Override
    public void test01() {
        System.out.println("子类重写父类的方法");
    }
    public void test03(){
        System.out.println("子类独有的方法");
    }
}

创建Demo01.java

public class Demo01 {
    public static void main(String[] args) {
        //-----------普通创建对象---------------
        //new Cat()创建对象 Cat cat = 是指Cat类的对象接收
        //cat 引用new Cat(),cat类型为Cat
        Cat cat = new Cat();
        //调用子类重写父类的方法
        cat.test01();
        //子类调用父类的方法
        cat.test02();
        //子类调用独有的方法
        cat.test03();

        System.out.println("--------------------");
        //-------------使用多态创建对象------------
        //animal引用new Cat(),animal类型为Animal
        //父类对象指向子类对象
        Animal aniaml = new Cat();
        aniaml.test01();
        aniaml.test02();
        //子类调用独有的方法,父类引用无法调用
        //aniaml.test03();
    }
}

课堂示例:

创建Animal.java

public abstract class Animal {
    public abstract void eat();
}

创建Cat.java

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

创建Demo.java

public class Demo {
/*    public void test01(Cat cat){
        cat.eat();
    }

    public void test02(Dog dog){
        dog.eat();
    }

    public void test03(Pig pig){
        pig.eat();
    }*/

    // 可以接收Animal类型的对象和Animal子类的对象
    public void test(Animal animal){
        animal.eat();
    }
}

创建Demo01.java

public class Demo01 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        Dog dog = new Dog();
        Pig pig = new Pig();
	
        Demo demo = new Demo();
	
        demo.test(cat);
        demo.test(dog);
        demo.test(pig);
    }
}

创建Dog.java

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

创建Pig.java

public class Pig extends Animal {
    @Override
    public void eat() {
        System.out.println("猪吃菜叶");
    }
}

使用

2、修饰符

2.1 abstract

abstract:抽象的

  • 1.abstract修饰的方法为抽象方法,必须存在抽象类中,没有方法体,子类必须重写
  • 2.abstract修饰的类为抽象类
  • 3.abstract不能修饰属性,构造方法,构造代码块
  • 4.抽象类有构造方法(抽象类会被继承),但是不能被实例化(存在抽象方法)
  • 5.抽象类中存在抽象方法,也能存在普通方法
  • 6.抽象类中可以只有普通方法,这样做的用作只是让类无法被实例化
  • 7.普通类继承抽象类,必须重写所有的抽象方法
  • 8.抽象类可以继承抽象类,可以有选择地进行重写其中的抽象方法

抽象类的使用场景:

  • 当父类存在一个或者多个子类必须重写的方法时,可以把父类写成抽象类
  • 减少了需要重写的父类方法的方法体,约束了子类必须重写对应的方法

创建Animal.java

public abstract class Animal {
    int age;

    public Animal(){

    }

    public void sleep(){
        System.out.println("趴着睡");
    }
    public abstract void eat();

    public abstract void test();
}

创建Cat.java

public class Cat extends NewAnimal{
    @Override
    public void eat() {
        System.out.println("猫吃猫粮");
    }

}

创建Demo01.java

public class Demo01 {
    public static void main(String[] args) {
        //抽象类不能被实例化
        /*Animal animal = new Animal();
        animal.eat();*/
    }
}

创建NewAnimal.java

public abstract class NewAnimal extends Animal{
    @Override
    public void test() {

    }
}

创建Person.java

// 抽象类中可以只存在普通方法
public abstract class Person {
    public void test(){

    }
}

2.2 final

2.2.1 什么是final(最终)

概念:最后的,不可更改的。

  • final可修饰的内容:
  • 类(最终类)
  • 方法(最终方法)
  • 变量(最终变量)
2.2.2 final类
  • final修饰类:此类不能被继承。
  • String、Math、System均为final修饰的类,不能被继承。
  • final修饰方法:此方法不能被覆盖(重写)。
  • 意为最终方法,不支持子类以覆盖的形式修改。
2.2.3 final变量

final修饰变量:此变量值不能被改变(常量)。

2.2.4 final常量
  • 静态常量不再提供默认值,必须手动赋予初始值。
  • 赋值时机:显示初始化、静态代码块。
2.2.5 final方法
  • 可以正常调用,可以被重载,不能被重写

创建Demo01.java

public class Demo01 {
    public static void main(String[] args) {
        User user = new User();
        user.test2();
        user.test2(1);

        Father father = new Father();

        String str = "";
    }
}

创建Father.java

public final class Father {
}

创建Person.java

public class Person extends User {
    /*public void test2(int num){
        System.out.println("final重写的方法");
    }*/
}

创建User.java

public class User /* extends Father*/{
    //final与static一起使用,名字一般为大写,多个单词用下划线进行区分,SYSTEM_NAME
    static final int ID = 1;
    public void test1(){
        //无法被重新赋值
        //id = 2;
    }

    public  void test2(){
        System.out.println("final修饰的方法");
    }

    public final void test2(int num){
        System.out.println("final重载的方法");
    }

   /* final 不能修饰构造方法
    public final User(){

    }*/
   /* final 不能修饰构造代码块
   final{

   }*/
}

3、接口

3.1 概念

接口:

  • 定义关键词interface,实现关键词implements
  • 接口相当于特殊的抽象类,定义方式、组成部分与抽象类类似。

特点:

  • 没有构造方法,不能创建对象。
  • 只能定义:公开静态常量、公开抽象方法。

其他:

  • 1.接口是一个特殊的抽象类,但不是类
  • 2.一个类可以多实现接口
  • 3.接口中的方法默认是抽象方法,访问修饰符默认是public
  • 4.接口中不能有普通方法,都是必须要被实现的抽象方法
  • 5.接口中的属性默认为静态常量,访问修饰符默认是public,不能私有化
  • 6.接口不存在构造方法,更不能被实例化
  • 7.接口不存在构造代码块
  • 8.接口不能实现接口
  • 9.接口可以多继承接口

10.JDK1.8新特性

  • 接口中允许存在default和static修饰的方法
  • default修饰的方法可以被重写,static修饰的方法不能被重写

isp:

  • 接口分离原则:一个接口只做一件事

面向对象设计原则:(开口合里最单依)

  • 开闭原则,
  • 接口分离原则,
  • 合成复用原则,
  • 里氏替换原则,
  • 最少原则(迪米特原则),
  • 单一原则,
  • 依赖原则

3.2 与抽象类的区别

相同点:

  • 可编译成字节码文件。
  • 不能创建对象。
  • 可以作为引用类型。
  • 具备Object类中所定义的方法。

不同点:

  • 所有属性都是公开静态常量,隐式使用public static final修饰。
  • 所有方法都是公开抽象方法,隐式使用public abstract修饰。
  • 没有构造方法、动态代码块、静态代码块。

创建Demo01.java

public class Demo01 {
}

创建Door.java

public abstract class Door {
    public abstract void open();

    public abstract void close();
}

创建FingerDoor.java

public class FingerDoor extends Door implements IFinger{
    @Override
    public void open() {
        System.out.println("开指纹门");
    }

    @Override
    public void close() {
        System.out.println("关指纹门");
    }


    @Override
    public void finger() {
        System.out.println("指纹解锁");
    }
}

创建IFace.java

//人脸识别的接口
public interface IFace {
    void face();
}

创建IFinger.java

//指纹解锁的接口
public interface IFinger {
    //接口中的方法默认是公开抽象的方法
    void finger();
}

创建IronDoor.java

//铁门
public class IronDoor extends Door{

    @Override
    public void open() {
        System.out.println("开铁门");
    }

    @Override
    public void close() {
        System.out.println("关铁门");
    }
}

创建StainlessDoor.java

//不锈钢门  --  能够进行指纹解锁和人脸识别
public class StainlessDoor extends Door implements IFinger,IFace{
    @Override
    public void open() {
        System.out.println("开不锈钢门");
    }

    @Override
    public void close() {
        System.out.println("关不锈钢门");
    }

    @Override
    public void finger() {
        System.out.println("指纹解锁不锈钢门");
    }

    @Override
    public void face() {
        System.out.println("人脸识别不锈钢门");
    }
}

创建TreeDoor.java

public class TreeDoor extends Door{
    @Override
    public void open() {
        System.out.println("开木门");
    }

    @Override
    public void close() {
        System.out.println("关木门");
    }
}

4、转型

instance of关键字

  • 判断关键词左边的对象是否为右边的类型,如果是则返回true
  • 向下转型前,应判断引用中的对象真实类型,保证类型转换的正确性。
  • 语法:父类引用 instance of 类型

4.1 向上转型

父类引用中保存真实子类对象,称为向上转型(即多态核心概念)。
注意: 仅可调用Animal中所声明的属性和方法。

4.2 向下转型

将父类引用中的真实子类对象,强转回子类本身类型,称为向下转型。
注意:只有转换回子类真实类型,才可调用子类独有的属性和方法。

4.3 代码示例

创建Animal.java

public class Animal {
}

创建Cat.java

public class Cat extends Animal {
    public void test01(){
        System.out.println("cat独有的方法");
    }
}

创建Dog.java

public class Dog extends Animal {
    public void test01(){
        System.out.println("dog独有的方法");
    }
}

创建Demo01.java

public class Demo01 {
    public static void main(String[] args) {
        /*
        //小类型转大类型   --  默认转换    --  向上转型	
        int num1 = 1;
        long num2 = num1;

        //大类型转小类型   --  强制转换    --  向下转型
        int num3 = 128;
        byte num4 = (byte)num3;//-128

        //引用数据类型转换
        //子类转父类       --  默认转换    --  向上转型
        Cat cat1 = new Cat();
        Animal animal1 = cat1;

        //父类转子类       --  强制转换    --   向下转型
        Animal animal2 = new Animal();
        Cat cat = (Cat)animal2;
        */

        /*
        会报类型转换异常
        Animal animal = new Cat();
        Dog dog = (Dog)animal;*/

        }
        Cat cat = new Cat();
        test(cat);
        Dog dog = new Dog();
        test(dog);
    }

    public static void test(Animal animal){
        //无法通过animal直接调用,因为test01是子类独有的方法
        //animal.test01()
        //判断animal是哪个子类对象,强转成对应的子类对象再调用独有的方法
        if(animal instanceof Cat){
            Cat cat = (Cat)animal;
            cat.test01();
        }else if(animal instanceof  Dog){
            Dog dog = (Dog)animal;
            dog.test01();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值