java_day8_多态、抽象类、接口

一、多态

多态的好处:
1、提高了程序的维护性(由继承保证)
2、提高了程序的扩展性(由多态保证)

代码案例(多态的拓展性)

class Animal{
    public void eat(){
        System.out.println("吃");
    }

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

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

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

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

    @Override
    public void sleep() {
        System.out.println("🐱蜷着睡");
    }
}

class Sheep extends Animal{
    @Override
    public void eat() {
        System.out.println("🐏吃草");
    }

    @Override
    public void sleep() {
        System.out.println("🐏趴着睡");
    }
}

class Turtle extends Animal{
    @Override
    public void eat() {
        System.out.println("🐢吃🥩");
    }

    @Override
    public void sleep() {
        System.out.println("🐢缩着睡");
    }
}

class AnimalTool{
    public static void useAnimal(Animal animal){
        animal.eat();
        animal.sleep();
    }

//    public static void useCat(Cat cat){
//        cat.eat();
//        cat.sleep();
//    }
//
//    public static void useDog(Dog dog){
//        dog.eat();
//        dog.sleep();
//    }
//
//    public static void useSheep(Sheep sheep){
//        sheep.eat();
//        sheep.sleep();
//    }
}

public class DuoTaiDemo1 {
    public static void main(String[] args) {
        //现在我想养一只🐕
        Dog d1 = new Dog();
//        d1.eat();
//        d1.sleep();
//        useDog(d1);
//        AnimalTool.useDog(d1);
        AnimalTool.useAnimal(d1);
        Dog d2 = new Dog();
//        d2.eat();
//        d2.sleep();
//        useDog(d2);
//        AnimalTool.useDog(d2);
        AnimalTool.useAnimal(d2);

        //我现在不想养🐕,我想养一只🐱
        Cat c1 = new Cat();
//        c1.eat();
//        c1.sleep();
//        useCat(c1);
//        AnimalTool.useCat(c1);
        AnimalTool.useAnimal(c1);

        //随着我们养的动物种类越来越多,我们发现
        //1. 自定义动物的类越来越多【这是不可避免】
        //2. 当前类中的useXxx的方法越来越多,写在这里其实并不合适,因为这是一个测试类
        //测试类中主要涉及创建对象调用功能
        //我们可以将调用动物功能的方法放到一个动物工具类中
        //我想养一只🐏
        Sheep s1 = new Sheep();
//        AnimalTool.useSheep(s1);
        AnimalTool.useAnimal(s1);

        //工具类是不应该频繁被修改的类,也就是说,我们写好一个工具类后,即便我们有新的动物出现,也不需要修改工具类也可以使用
        //利用多态的扩展性来使用
        //我想养一只🐢
        Turtle t1 = new Turtle();
        AnimalTool.useAnimal(t1);


    }

//    public static void useCat(Cat cat){
//        cat.eat();
//        cat.sleep();
//    }
//
//    public static void useDog(Dog dog){
//        dog.eat();
//        dog.sleep();
//    }
}

向下转型(当需要用到子类对象自己独有的方法时需要用向下转型)
格式: 子类类名 变量名 = (子类类名)要转型的变量名;

代码案例

class Fu1{
    public void fun1(){
        System.out.println("好好学习,天天向上!");
    }
}

class Zi1 extends Fu1{
    @Override
    public void fun1() {
        System.out.println("在数加好好学习,天天向上!");
    }

    public void show1(){
        System.out.println("现在没有睡觉...");
    }
}

class Demo1 extends Fu1{

}

public class DuoTaiDemo2 {
    public static void main(String[] args) {
        Fu1 f1 = new Zi1();
        f1.fun1();
//        f1.show1();
        //向下转型
        //格式: 子类类名 变量名 = (子类类名)要转型的变量名;
        Zi1 z1 = (Zi1)f1;
        z1.show1();
        //并不是任意两个类型之间都可以做向下转型,只有实际内存对象类型与要转的类型一样
//        Demo1 d1 = (Demo1) f1; //ClassCastException

    }
}

二、抽象类

java为了表示现实生活中抽象的概念集合,提供了一个关键字给我们使用:abstract
abstract 抽象的
可以修饰类,修饰成员方法

1. 被abstract修饰的类是抽象类, 抽象类不能被实例化
2. 被abstract修饰的方法是抽象方法, 抽象方法不能有大括号实现
3. 在抽象类,既可以存在具体实现的方法, 也可以存在抽象方法
4. 若一个类中有抽象方法, 这个类一定是一个抽象类
5. 当一个具体的类继承一个抽象类, 必须要实现抽象类中的所有抽象方法
6. 当一个抽象类继承一个抽象类的时候, 可以选择性地是否重写抽象方法

代码案例

abstract class Animal2{
    //拥有具体实现的方法
    public void eat1(){
        System.out.println("吃饭");
    }

    //抽象方法
    public abstract void eat2();
}

abstract class A1 extends Animal2{

}


class Dog2 extends Animal2{
    @Override
    public void eat2() {
        System.out.println("🐕吃🥩");
    }
}


public class AbstractDemo1 {
    public static void main(String[] args) {
//        Animal2 animal2 = new Animal2();
    }
}
抽象类与类中成员的关系:
    成员变量: 抽象类既可以存在变量, 也可以存在常量
    构造方法: 可以存在构造方法, 是为了将来在继承关系做初始化的作用
    成员方法: 既可以是具体的实现方法, 也可以是抽象方法

代码案例

abstract class Demo2{
//    int a = 10;
//    final int b = 20;

    Demo2(){}
}

class A2 extends Demo2{
    A2(){
//        super();
    }
}

public class AbstractDemo2 {
    public static void main(String[] args) {
//        Demo2 demo2 = new Demo2();
    }
}
  1. 一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
    可以表示一种概念的集合
  2. abstract不能和哪些关键字共存
    final 不能共存
    static 不能共存
    private 不能共存

代码案例

abstract class ShuJia{
//     abstract final void fun1(); // 非法的修饰符组合: abstract和final

//    abstract static void fun1(); // 非法的修饰符组合: abstract和static

//    private abstract void fun1(); // 非法的修饰符组合: abstract和private
}

public class AbstractDemo3 {
    public static void main(String[] args) {

    }
}

三、接口

接口:表示一个类的额外功能的实现
java提供了一个关键字表示接口:interface
接口我们可以将它看作成一个特殊的类, 因为接口也会被编译成一个class文件

接口注意事项:

  1. 接口中只能存在抽象方法, jvm默认会在方法前使用public abstract进行修饰, 刚学java推荐加上

  2. 类和接口是实现关系 可以通过关键字implements实现接口

  3. 当一个具体的类实现一个接口的时候, 必须要实现接口中所有的抽象方法

  4. 若一个抽象类实现一个接口的时候,可以选择性地实现接口中的抽象方法

  5. 一个类可以同时实现多个接口,使用逗号隔开

  6. 接口和接口存在继承关系, 并且一个接口可以同时继承多个接口

  7. 接口中只能定义常量, 默认修饰符为public static final

  8. 接口无法实例化, 接口中不能出现构造方法

     java中允许多继承吗?
     答:
         若是类和类之间的继承,只能单继承,不能多继承
         若是接口与接口之间的继承,可以多继承
    

代码案例

interface QiChe{
    public abstract void qiche();

//    public void fun1(){
//        System.out.println("好好学习");
//    }
}


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

class Bear extends Animal3{
    @Override
    public void eat(){
        System.out.println("🐻吃🥩");
    }
}

class QiCheBear extends Animal3 implements QiChe{
    @Override
    public void eat() {
        System.out.println("🐻吃🥩");
    }

    @Override
    public void qiche() {
        System.out.println("训练后的🐻会骑车");
    }
}

public class InterfaceDemo1 {
    public static void main(String[] args) {

    }
}
interface Inter{
    void fun1();
    void fun2();
}

interface Inter2 {
    void fun3();
}

interface Inter3 extends Inter,Inter2{
    //fun1();
    //fun2();
    //fun3();
    void fun4();
}



class Demo5 implements Inter,Inter2{

    @Override
    public void fun1() {

    }

    @Override
    public void fun2() {

    }

    @Override
    public void fun3() {

    }
}

abstract class Demo4 implements Inter{

}



class Demo1Impl implements Inter{

    @Override
    public void fun1() {

    }

    @Override
    public void fun2() {

    }
}

public class InterfaceDemo2 {
    public static void main(String[] args) {

    }
}
interface Inter1{
    public static final int a = 10;

//    Inter1(){}
}

class Demo6 implements Inter1{
    public void fun1(){
//        a = 20;
        System.out.println(a);
    }

}

public class InterfaceDemo3 {
    public static void main(String[] args) {
//        Demo6 demo6 = new Demo6();
//        System.out.println(demo6.a);
//        System.out.println(Inter1.a);
//        demo6.fun1();

//        Inter1 inter1 = new Inter1();

        Inter1 i1 = new Demo6(); // 接口多态
    }
}
posted @   w我自横刀向天笑  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示