Java中的多态,抽象类和接口

本文深入解析Java中的多态概念,探讨其在编译时与运行时类型的差异,以及多态的优缺点。同时,文章详细介绍了抽象类与接口的特点,包括抽象方法的定义、抽象类的实例化限制、接口的规范作用等,为读者提供了一个全面理解Java面向对象特性的视角。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

多态
  • Java引用变量有两个类型:

    • 编译时类型:由声明该变量时使用的类型决定

    • 运行时类型:由实际赋给该变量的对象决定

  • 如果编译时类型和运行时类型不一致,就可能出现所谓的多态。

    • 多态实际上就是,某一个事物,在不同时刻表现出来的不同状态。或者说,同一个变量,调用同一个方法时呈现出的多种不同的行为特征。

      例: Cat c=new Cat();
      Animal a=new Cat();
      猫可以是猫的类型。猫 m = new 猫();
      同时猫也是动物的一种,也可以把猫称为动物。动物 d = new 猫();

    • 多态的前提:

      1. 有继承关系
      2. 子类有重写父类的方法(没有也可以,但是多态就会没有意义)
      3. 父类引用指向子类对象,也就是说编译时类型由父类决定,运行时类型由子类决定。 ji即:父 fname = new 子();
    • 多态的优缺点:

      • 优点:提高了代码的维护性和延展性。
      • 缺点:不能使用子类特有的功能和属性
  • 多态的使用:

    public class MyTest {
        public static void main(String[] args) {
            Fu fu = new Zi();
            System.out.println(fu.a);
            //父类引用不能直接访问子类独有的属性
            System.out.println(fu.num);//编译出错
            fu.show();
            //父类引用不能直接访问子类独有的方法
            fu.test();//编译出错
            //向下转型
            Zi zi= (Zi) fu; 
            System.out.println(zi.num);
            zi.test();
        }
    }
    
    class Fu{
        int a=10;
        public void show(){
            System.out.println("父类的show方法");
        }
    }
    class Zi extends Fu{
        int num=10;
        @Override
        public void show() {
            System.out.println("重写父类的show方法");
        }
        public void test(){
            System.out.println("子类特有的方法");
        }
    }
    //结果:
    /*
        10
        重写父类的show方法
        10
        子类特有的方法
    */
    

    如下为多态的内存图解(网上的)

    [外链图片转存失败(img-r44OsLD3-1564286479497)(E:\西部开源\20190413-JavaSE-课件\多态的内存图解.bmp)]

抽象类
  • 某些情况下,某个父类只知道它的子类应该包含怎样的方法,但不知道子类如何实现这些方法,我们就可以将该类定义为抽象类,将这些不知如何实现的方法定义为抽象方法。即抽象类中定义的是该继承体系的共性功能。

  • 特点:

    • 抽象类和抽象方法必须用abstract关键字修饰,且抽象方法不能有方法体:

      abstract class name{}
      public abstract void show();
      
    • 抽象类不能被实例化,抽象类中的构造方法用于子类访问父类数据时的初始化即用于被子类调用。

    • 含有抽象方法的类只能被定义为抽象类,也就是说抽象类不一定有抽象方法,有抽象方法的类一定是抽象类

    • 抽象类的子类要么重写父类的所有抽象方法,要么也被定义为抽象类。

    • 抽象类可以有成员变量,普通方法,构造方法,初始化块,内部类

    • abstract不能喝final,private,static共存

  • public class Test {
        public static void main(String[] args) {
            Fu p = new Zi();
            p.show();
        }
    
    }
    
    abstract class Fu{
        int num = 10;
        public Fu() {
        }
    
        public abstract void show();
        public void method(){
            System.out.println("抽象类的普通方法");
        }
    }
    
    class Zi extends Fu{
        int x = 10;
    
        public Zi() {
        }
    
        @Override
        public void show() {
            System.out.println("重写show()方法");
        }
    }
    
接口
  • 接口是用来定义一些规范(规则)来实现一些扩展功能

  • 特点

    • 由interface关键字修饰,类实现接口要用implements关键字

    • 因为接口中定义的是一种规范,因而接口中没有构造方法

    • 接口中的变量默认使用public static final修饰,也就是说接口中只能定义静态常量。

    • 接口中的方法必须是抽象方法,类方法(由static修饰的方法)或者默认方法(default修饰的方法),不可以有非抽象方法。

    • 类可以实现多个接口:

      public class name  extends 父类 implements 接口1,接口2...
      {
          类体
      }
      
  • public class MyTest {
        public static void main(String[] args) {
            A a = new B();
            a.show();
            //强制向下转型
            System.out.println(((B) a).b);
        }
    }
    
    interface A{
        //接口中成员变量前面有默认的修饰符  public static final
        int num=100;
        public static final  int A=1000;
    
       //方法前面存在默认修饰符 public abstract
        public abstract void show();
    }
    
    class B implements A{
        int b = 0;
    
        public B() {
        }
    
        @Override
        public void show() {
            System.out.println("重写show方法");
        }
    }
    
Java 中,**多态接口抽象类** 是面向对象编程的核心组成部分之一。下面我们分别对这三个概念进行详细介绍,并探讨它们之间的联系。 --- ### **1. 多态** 多态是指同一个方法调用可以根据实际的对象类型表现出不同的行为。它分为两种形式: - **编译时多态(静态多态)**: 主要是通过方法重载 (`method overloading`) 实现的。 - **运行时多态(动态多态)**: 通常是通过方法重写 (`method overriding`) 来实现的。 #### 示例代码: ```java class Animal { void makeSound() { System.out.println("动物发出声音"); } } class Dog extends Animal { @Override void makeSound() { // 方法重写 System.out.println("汪汪"); } } public class TestPolymorphism { public static void main(String[] args) { Animal myAnimal = new Dog(); // 动态绑定 myAnimal.makeSound(); // 输出 "汪汪" } } ``` 在这个例子中,`myAnimal` 的静态类型是 `Animal`,但实际上它的运行时类型是 `Dog`,因此调用了 `Dog` 类中的 `makeSound()` 方法。这就是典型的运行时多态的表现。 --- ### **2. 接口** 接口是一种完全抽象化的类,其中的所有方法都没有具体实现(Java 8 开始支持默认方法静态方法)。接口主要用于定义一组规范,规定了哪些方法需要被实现,但并不提供这些方法的具体内容。 #### 特点: - 一个类可以同时实现多个接口。 - 接口中的所有字段都是 `public final static` 属性。 - 接口中所有的方法默认是 `public abstract`。 #### 示例代码: ```java interface Flyable { void fly(); } class Bird implements Flyable { @Override public void fly() { System.out.println("鸟儿飞翔..."); } } public class TestInterface { public static void main(String[] args) { Flyable bird = new Bird(); // 接口类型的引用指向实现了该接口的对象 bird.fly(); // 输出 “鸟儿飞翔...” } } ``` 在这里,`Bird` 类实现了 `Flyable` 接口,并提供了具体的飞行逻辑。 --- ### **3. 抽象类** 抽象类是用来捕获子类共同特征的一种特殊类。与普通类的区别在于它可以包含未实现的方法(抽象方法),并且不能直接实例化。 #### 特点: - 抽象类可以拥有构造方法,但它仅能由其非抽象子类调用。 - 子类继承抽象类时必须实现所有的抽象方法(除非自身也是抽象类)。 - 一个类最多只能继承一个抽象类,但是可以实现多个接口。 #### 示例代码: ```java abstract class Vehicle { String color; public Vehicle(String color) { this.color = color; } abstract void run(); void showColor() { System.out.println("颜色:" + color); } } class Car extends Vehicle { public Car(String color) { super(color); // 调用父类构造器 } @Override void run() { System.out.println("汽车行驶中..."); } } public class TestAbstractClass { public static void main(String[] args) { Vehicle car = new Car("红色"); // 父类引用指向子类对象 car.showColor(); // 输出 “颜色:红色” car.run(); // 输出 “汽车行驶中...” } } ``` 在此示例中,`Vehicle` 是一个抽象类,而 `Car` 继承自它并实现了抽象方法 `run()`。 --- ### **三者的结合** 实际上,在复杂的项目中,我们常常会将多态接口抽象类结合起来使用。例如: - 将公共的行为抽取到抽象类中; - 将某些特殊的约束条件放在接口里; - 最终通过多态的方式统一管理调用。 这样的组合能够提升代码的复用性可维护性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值