首页 > 其他分享 >抽象类

抽象类

时间:2025-01-13 22:35:29浏览次数:1  
标签:子类 实例 Animal 抽象类 方法 public

抽象类

abstract 修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。

  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类

  • 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的通过多态来实例对象

  • 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的,

  • 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。

在面向对象编程中,抽象类是一个不能直接实例化的类,它通常作为其他类的基类,提供通用的接口和部分实现。抽象类的主要目的是为继承它的子类提供一个模板,确保所有子类都实现特定的功能。

主要特点:

  1. 不能实例化:抽象类不能被直接实例化。你不能创建抽象类的对象,必须通过继承它的子类来实例化。
  2. 可以包含抽象方法:抽象类可以包含抽象方法(方法声明没有实现),这些方法需要在子类中实现。抽象方法在抽象类中只定义方法签名(包括方法名、参数列表和返回类型),而没有方法体。
  3. 可以有已实现的方法:除了抽象方法,抽象类还可以包含已实现的方法,这些方法可以被子类继承和重用,或者被子类覆盖(重写)。
  4. 可以有成员变量:抽象类可以包含成员变量,允许它在多个子类中共享一些数据。
  5. 可以继承其他类:抽象类可以继承其他类,并且可以实现接口。

抽象类的定义与使用

假设我们有一个动物类 Animal,我们希望定义一个通用的行为,但不希望直接实例化 Animal 类,而是让它的子类具体实现某些特性。

package com.oop.demo09;

public class Test {
    public static void main(String[] args) {
        //new Animal(); //抽象类的实例不是直接new 而是通过多态 父类(抽象类)的引用指向子类的实例
        Animal d1 = new Dog();//通过子类将父类(抽象类中的抽象方法)实现且必须全部实现 否则就将子类也声明成抽象类
        System.out.println(d1.num);
        System.out.println(d1.num_float);
        d1.breath();//父类的引用 直接调用自己的方法(子类没有重写)
        d1.sound();//子类实例 用重写过的抽象类中抽象方法
        Animal c1 = new Cat();
        System.out.println(c1.num);
        System.out.println(c1.num_float);
        c1.breath();//父类的引用 直接调用自己的方法(子类没有重写)
        c1.sound();//子类实例 用重写过的抽象类中抽象方法
    }
}

abstract class Animal {
    public static int num = 123;
    public float num_float=123.456f;
    //抽象类中可以定义属性
    public void breath(){   //抽象类可以定义普通方法
        System.out.println("他在呼吸!");
    }
    public abstract void sound(); //只有方法的声明,没有方法体

    //new Animal();//抽象类不能直接实例化,得借助子类进行实例化(多态)
    //new Dog();//也不能在抽象类里面实例对象

}
class Dog extends Animal{
    public void sound(){
        System.out.println("Bark!");//在子类中将抽象方法具体实现
    }
}
class Cat extends Animal{
    public void sound(){
        System.out.println("Miao Miao!");
    }
}

抽象类中可以有:

1. 定义属性

抽象类可以定义属性(成员变量),这些属性可以是静态的(static)或实例的。它们可以被继承到子类中。

public static int num = 123;  // 静态属性
public float num_float = 123.456f;  // 实例属性
  • num 是一个静态属性,可以直接通过 Animal 类名访问,并且是所有 Animal 类型(包括继承类)共享的。
  • num_float 是一个实例属性,每个 Animal 的实例都有自己的副本,子类实例也可以访问该属性。

2. 定义普通方法

抽象类可以定义普通(已实现)的方法,子类可以继承并直接使用这些方法,也可以选择覆盖(重写)。

public void breath() {  
    System.out.println("他在呼吸!");
}
  • breath 是一个普通方法,定义在抽象类 Animal 中。它不需要在子类中重写,子类可以直接继承并调用它。

3. 定义抽象方法

抽象类中可以定义抽象方法,这些方法没有方法体,必须由子类实现。

public abstract void sound(); // 抽象方法,要求子类必须实现
  • sound 是一个抽象方法,在 Animal 类中没有实现,子类 DogCat 必须实现这个方法。

4. 构造方法

抽象类可以有构造方法,但它不能直接实例化。在构造方法中,你可以初始化一些共享的成员或执行其他必要的初始化操作。

abstract class Animal {
    public Animal() {
        System.out.println("动物类构造方法");
    }
    // 其他代码
}
  • Animal 类可以包含构造方法,尽管我们不能直接实例化抽象类,但可以在子类实例化时调用父类的构造方法。

5. 静态方法

抽象类也可以有静态方法(static),这些方法只能通过类名访问,而不依赖于实例。

abstract class Animal {
    public static void staticMethod() {
        System.out.println("这是抽象类的静态方法");
    }
}
  • 你可以通过 Animal.staticMethod() 来调用静态方法,而不需要创建实例。

6. 接口实现

抽象类可以实现接口。这样,抽象类就可以强制要求所有子类实现接口中的方法,同时又可以提供一些默认的实现。

java复制代码interface Eater {
    void eat();
}

abstract class Animal implements Eater {
    // 可以不实现接口方法,留给子类去实现
    public abstract void sound();
}

总结:在您的代码中,抽象类的以下特性已经体现出来:

  • 可以定义成员变量(静态和实例变量)。
  • 可以定义普通方法(有方法体的方法)静态方法和非静态方法。
  • 可以定义抽象方法(没有方法体的方法,要求子类实现)。
  • 可以包含构造方法
  • 子类必须实现抽象类中的所有抽象方法,除非子类本身也是抽象类。

但是,抽象类可以有更多的功能,如:

  • 静态方法。
  • 可以实现接口。
  • 可以包含常量(public static final)等。

抽象类中的属性只能是常量吗?

不,抽象类中的属性不仅仅可以是常量,它也可以是普通的实例变量(非常量)。抽象类中的属性可以是:

  1. 实例变量(非常量)
  2. 静态变量(常量或非常量)
  3. 常量public static final

1. 实例变量(非常量)

抽象类可以定义实例变量(成员变量),这些变量属于类的实例。每个继承该抽象类的子类对象都有自己独立的副本。子类可以直接访问这些变量,或者通过重写的方法来访问和修改它们。

abstract class Animal {
    public float num_float = 123.456f;  // 实例变量
}
  • num_float 是实例变量,每个实例(包括子类的实例)都有这个变量的副本。子类可以直接访问它。

2. 静态变量(常量或非常量)

抽象类也可以包含静态变量,这些变量属于类本身而不是类的实例。所有通过该类或子类访问这个变量时,都访问的是相同的内存位置。

abstract class Animal {
    public static int num = 123;  // 静态变量
}
  • num 是静态变量,所有 Animal 类及其子类共享这个变量。你可以通过 Animal.num 来访问它。

3. 常量public static final

常量是指一旦被赋值就不能改变的变量。常量通常是静态的,意味着它们是属于类的,而不是某个实例的。常量在抽象类中使用时一般都加上 public static final 修饰符。

abstract class Animal {
    public static final String TYPE = "动物";  // 常量
}
  • TYPE 是一个常量,public static final 表示它是类级别的,且值不可更改。它被所有继承 Animal 类的子类共享。
package com.oop.demo09;

public class Test {
    public static void main(String[] args) {
        //new Animal(); //抽象类的实例不是直接new 而是通过多态 父类(抽象类)的引用指向子类的实例
        Animal.eat();//通过类名直接引用抽象类中的静态方法
        Animal d1 = new Dog();//通过子类将父类(抽象类中的抽象方法)实现且必须全部实现 否则就将子类也声明成抽象类
        System.out.println(d1.num);
        System.out.println(d1.num_float);
        d1.breath();//父类的引用 直接调用自己的方法(子类没有重写)
        d1.sound();//子类实例 用重写过的抽象类中抽象方法
        Animal c1 = new Cat();
        System.out.println(c1.num);
        System.out.println(c1.num_float);
        c1.breath();//父类的引用 直接调用自己的方法(子类没有重写)
        c1.sound();//子类实例 用重写过的抽象类中抽象方法
    }
}

abstract class Animal {
    //抽象类中可以定义属性  静态的 非静态的都可以
    public static int num = 123;
    public float num_float=123.456f;
   //抽象类可以定义构造器
    public Animal(){

    }
    //抽象类可以定义静态方法
    public static void eat(){
        System.out.println("他在吃东西!");
    }
    public void breath(){   //抽象类可以定义实例方法
        System.out.println("他在呼吸!");
    }

    public abstract void sound(); //只有方法的声明,没有方法体

    //new Animal();//抽象类不能直接实例化,得借助子类进行实例化(多态)
    //new Dog();//也不能在抽象类里面实例对象

}
class Dog extends Animal{
    public void sound(){
        System.out.println("Bark!");//在子类中将抽象方法具体实现
    }
}
class Cat extends Animal{
    public void sound(){
        System.out.println("Miao Miao!");
    }
}

输出结果:

他在吃东西!
123
123.456
他在呼吸!
Bark!
123
123.456
他在呼吸!
Miao Miao!

标签:子类,实例,Animal,抽象类,方法,public
From: https://www.cnblogs.com/panghuhu-space/p/18669545

相关文章

  • Spark 源码分析(一) SparkRpc中序列化与反序列化Serializer的抽象类解读 (java序列化部
    目录(3)JavaSerializerInstance定义了一个Java序列化实例(1)构造方法参数(2)方法1:serializeStream(3)方法2:deserializeStreamdefaultClassLoader(4)方法3:deserializeStreamloader(5)方法4:serialize(6)方法5:deserializeloader(7)方法6:deserializedefaul......
  • Spark 源码分析(一) SparkRpc中序列化与反序列化Serializer的抽象类解读 (正在更新中~)
    接上一章请先看解读序列化抽象类第一部分目录接上一章请先看解读序列化抽象类第一部分2.Java序列化实现类JavaSerializer(1)JavaSerializationStream类定义了一个java序列化流继承了SerializationStream抽象类代码实际例子1:序列化(2)JavaDeserializationStream......
  • java抽象类(abstract)与接口(Interface)的区别
    一、抽象类与接口的区别下面比较一下两者的语法区别:1.抽象类可以有构造方法,接口中不能有构造方法。2.抽象类中可以有普通成员变量,接口中没有普通成员变量3.抽象类中可以包含非抽象的普通方法,接口中的可以有非抽象方法,比如deaflut方法4.抽象类中的抽象方法的访问类型可以是......
  • JavaScript的抽象类(Abstract Classes)
    Python基础引言Python是一种广泛使用的高级编程语言,因其简单易学、功能强大而受到程序员的青睐。无论是数据分析、人工智能、Web开发,还是自动化脚本,Python都能为开发者提供便利。本文将介绍Python的基础知识,包括Python的基本语法、数据类型、控制结构、函数、模块和文件操......
  • C++面向对象编程:纯虚函数、抽象类、虚析构、纯虚析构
    纯虚函数的目的便是,父类不需要去实现,全部都是在子类中实现,有纯虚函数的话,就是抽象类,而且子类必须重写这个纯虚函数。可见以下代码:#include<iostream>usingnamespacestd;classami{public: virtualvoideat()=0;//纯虚函数,有纯虚函数的便是抽象类};classcat:......
  • Java难绷细节02---抽象类中只能有抽象方法吗以及有关抽象类的细节探讨
    Java难绷细节02---抽象类中只能有抽象方法吗以及有关抽象类的细节探讨标题长的像轻小说首先回答标题抛出的问题——False显然,有抽象方法的类是抽象类,但是,抽象类中只能有抽象方法吗?抽象类可以包含抽象方法,也可以包含具体方法如果一个类包含至少一个抽象方法,用abstract关键字修......
  • Java接口与抽象类深度探索
    一、接口1.接口是对行为(方法)的抽象2.为什么设计接口?继承的缺点1:只支持单继承,一个子类只有一个父类,继承的本质是代码的复用。继承的缺点2:继承过来的变量,方法不一定适合子类(父类的代码不一定完全适合子类,这时子类一般会进行重写)接口特点:支持多继承,一个类实现(继承)多个接口;接......
  • 抽象类和抽象函数
    基本概念被抽象关键字abstract修饰的类抽象类不能被实例化,可以包含抽象方法继承抽象类必须重写其抽象方法abstractclassThing{//抽象类中封装的所有知识都可以用publicstringname;}classWater:Thing{}//不能被实例化,但是可以适用里氏替换原则Thing......
  • C++的interface与抽象类
    提示:文章文章目录前言一、背景二、C++的interface与抽象类c++有interface关键词吗?c++抽象类有abstract关键词吗?所以c++抽象类和abstract没有关系。那什么是抽象类?题目1题目2什么是抽象函数?抽象函数和纯虚函数的区别?纯虚函数和虚函数的区别三、extends和implements2.......
  • Java笔记(抽象类、接口、内部类、final关键字)
    Java笔记(抽象类、接口、内部类、final关键字)(一).抽象类抽象方法所在的类就是抽象类,抽象方法是在public和void中间加一个abstract,表示子类继承父类(父类是抽象类)的方法时必须重写,否则直接报错1.抽象方法和抽象类2.抽象类和抽象方法的定义格式3.抽象类和抽象方法的注意......