java 抽象类 详解

这篇具有很好参考价值的文章主要介绍了java 抽象类 详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、抽象类概述:

二、抽象方法 : 

        1.概述 : 

        2.应用 : 

        3.特点 : 

三、抽象类特点 : 

        1.关于abstract关键字 : 

        2.抽象类不能被实例化,只能创建其子类对象 : 

        3.抽象类子类的两个选择 : 

四、抽象类的成员 : 

        1.成员变量 : 

        2.成员方法 : 

        3.构造器 : 

        4.总结 : 

        5.代码演示 : 

五、抽象类课堂练习 : 

        1.要求 : 

        2.思路 : 

        3.代码 : 

六、总结 :


抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

一、抽象类概述:

        我们知道,类用来模拟现实事物。一个类可以模拟一类事物,而某个类的一个实例化对象可以模拟某个属于该类的具体的事物。类中描绘了该类所有对象共同的特性,当一个类中给出的信息足够全面时,我们就可以实例化该类;比方说,在Dog类中定义了name,age,fur_color,sex等属性,以及habit,eat等行为时,我们就可以创建一个Dog类对象,来模拟某个具体的Dog,比如你家的宠物狗,或者是神犬小七等。但是,当一个类中给出的信息不够全面时,(比方说有无法确定的行为),它给出的信息不足以描绘出一个具体的对象,这时我们往往不会实例化该类,这种类就是抽象类打个比方,对于Animal类,是,所有的动物都有吃喝的行为,定义eat方法可以描述动物“吃”这一行为,但是每种动物吃的都不一样,因此一个eat方法并不能准确描述吃什么,怎么吃。这时Animal给出的信息就不足够描述一个对象,我们就不能去实例化Animal类。
        在Java中,我们通过在类前添加关键字abstract(抽象的)来定义抽象类。如下图所示 : 

public abstract class Animal {
    //Animal类此时就是一个抽象类。
}

class Dog extends Animal {
    //Dog类继承了Animal类,是Animal类的子类。
}

二、抽象方法 : 

        1.概述 : 

                我们将“只有方法声明,没有方法体”的一类方法统称为抽象方法抽象方法用关键字abstract修饰。需要注意的是,如果一个方法已经确定是抽象类,那么它绝不能再有方法体,即不能出现大括号,而是只需要在()后面添加一个分号即可,否则IDEA会提示报错信息,如下图所示 : 

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

                还要注意一点,如果某个类中已经出现了抽象方法,那这个类必须定义成抽象类,否则会报错,如下GIF动图演示——我们删掉Animal类前的abstract修饰符,IDEA立马就会给出提示信息,如下 : 

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

                也就是说,拥有抽象方法的类一定是抽象类;但是抽象类不一定有抽象方法。

        2.应用 : 

                当父类需要定义一个方法,却不能明确该方法的具体实现细节时,可以将该方法定义为abstract,具体实现细节延迟到子类。(让子类重写这个方法)
                就比如我们刚才说的——Animal类中的eat() 方法,我们可以先将其定义为抽象类,然后在子类中,比如说Dog类中重写eat() 方法,给出对Dog类对象“吃”这一行为的一些具体描述。
                up以Animal类,Dog类和Test类为例代码如下

package knowledge.polymorphism.about_abstract.introduction;

public abstract class Animal {   /** 父类 */
    //将Animal类中的eat() 方法定义为抽象类,具体实现延迟到子类。
    public abstract void eat();
}

class Dog extends Animal {      /** 子类 */
    //子类重写父类的抽象方法,也称为子类实现了该抽象方法。
    public void eat() {
        System.out.println("狗是杂食性动物,喜食肉类,喂养时应该以动物蛋白为主,素食为辅。");
    }
}

class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
    }
}

                 运行结果 : 

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

        3.特点 : 

               若父类中定义了一个抽象方法要求其所有非抽象子类都必须重写该抽象方法。否则IDEA会报错如下图所示

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

                前面我们说了,抽象方法用abstract关键字修饰。这里再补充一点——抽象方法不能再使用private,final 或者static关键字来修饰,即abstract不能与private,final或static共同出现,这是因为定义抽象方法的目的就是想将方法的具体实现延迟到子类,最终是要被子类重写的,而private,final,static这几个关键字都和“方法重写”的目的背道而驰
                如果你固执己见,非要让abstract和这几个关键字一同出现,IDEA也是毫不客气,直接报错,如下图所示

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

三、抽象类特点 : 

        1.关于abstract关键字 : 

                abstract关键字只能用于修饰类和方法,用于声明抽象类和抽象方法。其中,抽象类必须使用abstract关键字修饰声明时格式如下 : 

        访问权限修饰符  abstract  class  类名{ // }

        访问权限修饰符  abstract  返回值类型  方法名(形参列表);

                举个例子,如下 : 

//抽象类
public abstract class Animal {
    //抽象方法
    public abstract void eat();        //抽象方法最后加一个分号即可,不可以有大括号。
}

        2.抽象类不能被实例化,只能创建其子类对象 : 

                即,我们不能创建抽象类对象(这里的对象指的是堆空间中真正的对象,即不能“new 抽象类”),原因我们在开篇抽象类的概述中也提到了,这里不再赘述。如果你头铁,非要创建抽象类对象,IDEA也不是吃素的,直接报错,如下图所示 : 

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

                 当然,如果抽象类的子类没有用abstract关键字修饰,那么我们可以创建其子类对象,如下图所示 : 

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

        3.抽象类子类的两个选择 : 

                如果某个类继承了一个抽象类,那么这个类有两个选择——要么实现父类所有的抽象方法,要么子类本身也定义成抽象类。当然,肯定也不会是瞎jb想定义成抽象类就定义成抽象类的😂,要满足我们我们上面所说的定义抽象类的条件——类中提供的信息不足以描述一个对象,或者类中有无法确定的行为需要延迟到子类实现。

                还是给大家举个栗子。up现在在character包下创建一个Food类,将Food类定义为抽象类,并定义showNutrition()抽象方法,该方法将来要打印出食物的主要营养,具体实现延迟到子类;然后分别创建子类Meat类和Fruit类去继承Food类,我们在Meat类中重写Food类的showNutrition() 方法,使其打印出肉类的主要营养价值;同时,另一个子类Fruit类不去实现showNutrition() 方法,而是将其定义为抽象类。最后,以Test类为测试类,在测试类中创建子类对象并调用showNutrition() 方法。
                Food类,Meat类,Fruit类,Test类代码如下

package knowledge.polymorphism.about_abstract.character;

public abstract class Food {            /** 父类 : Food类 */
    //记住,抽象方法没有方法体
    public abstract void showNutrition();
}

class Meat extends Food {               /** 子类 : Meat类 */
    @Override
    public void showNutrition() {
        System.out.println("肉类是蛋白质、脂肪、维生素B2、维生素B1、烟酸和铁的重要来源。");
    }
}

abstract class Fruit extends Food {     /** 子类 : Fruit类 */
}
    
class Test {                            /** 测试类 : Test类 */
    public static void main(String[] args) {
        Meat meat = new Meat();
        meat.showNutrition();
    }
}

                 运行结果 : 

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

                 我们也可以再定义一个CiLi类表示水果中的刺梨,然后让刺梨类去继承Fruit类,并在CiLi类中去实现showNutrition() 方法Fruit类不变,Test类和CiLi类代码如下

class CiLi extends Fruit {
    @Override
    public void showNutrition() {
        System.out.println("刺梨是当之无愧的水果界的VC之王,VC含量高达2585mg/100g!");
    }
}

class Test {
    public static void main(String[] args) {/** 测试类 : Test类 */
        Meat meat = new Meat();
        meat.showNutrition();
        System.out.println("----------------------------------------");

        CiLi ciLi = new CiLi();
        ciLi.showNutrition();
    }
}

                运行结果 : 

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

四、抽象类的成员 : 

        1.成员变量 : 

        抽象类既可以有静态的成员变量,也可以有非静态的成员变量
        既可以有静态的成员常量,也可以有非静态的成员常量

        2.成员方法 : 

        抽象类既可以有(非私有的)抽象方法(注意抽象方法一定是非私有非静态非final,因为abstract关键字与private关键字,final关键字,static关键字不能同时存在);

        也可以有非抽象方法(非抽象方法就可以用private,final和static关键字来修饰了,具体使用时,根据实际需求合理应用)。

        3.构造器 : 

        抽象类可以和非抽象类一样拥有构造器,并且支持构造器的重载。

        4.总结 : 

        其实吧,说上面一大堆都是废话😂。

        抽象类中的成员只比非抽象类多一种——抽象方法。其他都和非抽象类一样。

        大家只要记住抽象方法怎么写,怎么用就彳亍了。😎

        5.代码演示 : 

                up以Fruit类为演示类,代码如下

package knowledge.polymorphism.about_abstract.about_members;

public abstract class Fruit {        //Fruit类是抽象类
//抽象类中可定义的成员:
    //1.非静态变量和静态变量
    private String name = "水果名儿是有长有短";
    private static String size = "水果的大小是有大有小";

    //2.非静态常量和静态常量
    public final String COLOR = "水果的颜色是五光十色";
    public static final String FORM = "水果的形态是千奇百怪";

    //3.抽象方法和非抽象方法
    public abstract void nutrition();
    private final static void suitCrowds() {
        System.out.println("人人都适合吃水果!");
    }
    public void invokeSuitCrowds() {
        Fruit.suitCrowds();
    }

    //4.构造器可以重载
    public Fruit() {
        System.out.println("Fruit's name = " + name);
    }
    public Fruit(String name) {
        this.name = name;
    }
}

                这些成员都可以在抽象类中定义,只要语法正确,IDEA是不会报错的,当然,具体怎么使用这些成员就看你自己了,根据实际情况来定。 

五、抽象类课堂练习 : 

        1.要求 : 

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

                如上图所示 : 

                已知西风骑士团的三位骑士分别是琴,可莉和优菈,请分别定义类来描述它们,要求给出每一个西风骑士的姓名,年龄和性别;并且,这三人均可以使用元素之力,分别是元素战技和元素爆发,但每位骑士的战技和爆发都不一样。其中,琴使用风元素,元素战技为风压箭,元素爆发为蒲公英之风可莉使用火元素,元素战技为蹦蹦炸弹,元素爆发为轰轰火花优菈使用冰元素,元素战技为冰朝的涡旋,元素爆发为凝浪之光剑。请在这些类中正确选择一个类定义成抽象类,并在该类中定义抽象方法elemental_kill() 和 elemental_burst(),要求这两个抽象方法将来在实现时,需要在控制台打印出当前骑士的元素战技和元素爆发;并在该抽象类中定义非抽象方法,要求该方法可以在控制台打印出当前骑士的基本信息。

        2.思路 : 

                阅读提干后我们得知,总共有三个角色,这三个角色均属于名为“西风骑士团”的一个组织。因此,我们可以分别定义四个类来分别描述“西风骑士团”,“琴”,“可莉”,“优菈”,再加上测试类,因此我们总共需要定义五个类
                “西风骑士团”可以代表一类人,由于每位骑士的元素战技和元素爆发均不相同,这个类并不能提供足够的信息来描述一个具体的“骑士”对象。所以,我们可以定义Knights类来表示“西风骑士团”,并将其定义为抽象类又因为琴,可莉,优菈均属于西风骑士团的一员,因此我们可以分别定义Qin类,Keli类以及Youla类来描述这三位骑士,并让Qin类,Keli类和Youla类继承Knights类
                题干要求定义两个抽象方法elemental_kill() 和 elemental_burst()来分别打印出当前骑士的元素战技和元素爆发。既然我们已经确定Knights类为抽象类,这就没啥好说了,在Knights类中定义这两个方法即可。
               又因为题干还要求我们在抽象类中定义方法打印出当前骑士的基本信息,因此,我们可以在Knights类定义name,age,sex这些属性;根据JavaBean标准,我们需要将这些属性全部设为私有,并给出公共的访问这些属性的方法,然后给出Knights类的无参构造和带参构造(注意,Knights是抽象类,无法被实例化,因此我们给出Knights构造器的目的不是为了创建Knights类对象,而是为了在子类的带参构造中使用super语句调用父类构造器;接着,再定义一个printInfo方法,用于打印出当前骑士的姓名,年龄和性别
                最后,我们可以定义测试类Test类,并分别创建Qin类,Keli类和Youla类对象,调用elemental_kill()方法,elemental_burst() 方法,以及printInfo方法

        3.代码 : 

                代码如下 : 

package knowledge.polymorphism.about_abstract.exercise;

public abstract class Knights {             /** 骑士类 */
    private String name;
    private int age;
    private String sex;

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

    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 String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }

    public abstract void elemental_skill();
    public abstract void elemental_burst();

    public void printInfo() {
        System.out.println("西风骑士——" + getName() + "," + getAge() + "岁,性别" + getSex());
    }
}

class Qin extends Knights{                  /** 琴类 */
    public Qin(String name, int age, String sex) {
        super(name, age, sex);
    }

    @Override
    public void elemental_skill() {
        System.out.println("琴的元素战技是风压箭。");
    }

    @Override
    public void elemental_burst() {
        System.out.println("琴的元素战技是蒲公英之风。");
    }
}
class Keli extends Knights{                 /** 可莉类 */
    public Keli(String name, int age, String sex) {
        super(name, age, sex);
    }

    @Override
    public void elemental_skill() {
        System.out.println("可莉的元素战技是蹦蹦炸弹。");
    }

    @Override
    public void elemental_burst() {
        System.out.println("可莉的元素战技是轰轰火花。");
    }
}
class Youla extends Knights{                /** 优菈类 */
    public Youla(String name, int age, String sex) {
        super(name, age, sex);
    }

    @Override
    public void elemental_skill() {
        System.out.println("优菈的元素战技是冰朝的涡旋。");
    }

    @Override
    public void elemental_burst() {
        System.out.println("优菈的元素战技是凝浪之光剑。");
    }
}

class Test {                                /** 测试类 */
    public static void main(String[] args) {
        Qin qin = new Qin("琴", 22, "female");
        qin.elemental_skill();
        qin.elemental_burst();
        qin.printInfo();
        System.out.println("-------------------------------------------");

        Keli keli = new Keli("可莉", 500, "female");
        keli.elemental_skill();
        keli.elemental_burst();
        keli.printInfo();
        System.out.println("-------------------------------------------");

        Youla youla = new Youla("优菈", 21, "female");
        youla.elemental_skill();
        youla.elemental_burst();
        youla.printInfo();
    }
}

                运行结果 : 

抽象类,# 核心基础,Java基础,java,jvm,开发语言,抽象类,OP,Java

六、总结 : 

        🆗,以上就是本节抽象类相关的全部内容了,大家一定要牢记抽象类和抽象方法的特点,牢记抽象类和抽象方法之间的关系,掌握abstract关键字的使用。下一节内容是多态章的final关键字,我们不见不散😆。感谢阅读!

        System.out.println("END--------------------------------------------------------------------------------");文章来源地址https://www.toymoban.com/news/detail-738486.html

到了这里,关于java 抽象类 详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java 抽象类 详解

    目录 一、抽象类概述: 二、抽象方法 :          1.概述 :          2.应用 :          3.特点 :  三、抽象类特点 :          1.关于abstract :          2.抽象类不能被实例化,只能创建其子类对象 :          3.抽象类子类的两个选择 :  四、抽象类的成员 :       

    2024年02月06日
    浏览(26)
  • Java抽象类详解

    在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是来描绘对象的, 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类 。比如: 说明 1.矩形,三角形,圆形都是图形,因此和Shape类的惯性应该是继承关系

    2024年02月11日
    浏览(24)
  • 【JavaSE】Java基础语法(十六):抽象类

    当我们在做子类共性功能抽取时,有些方法在父类中并没有具体的体现,这个时候就需要抽象类了! 在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽 象类! 抽象类和抽象方法必须使用 abstract 修饰 抽象类中不一定有抽

    2024年02月07日
    浏览(40)
  • 【Java基础】AQS (AbstractQueuedSynchronizer) 抽象队列同步器

    关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 我们继续总结学习 Java基础知识 ,温故知新。 CLH(Craig, Landin, and Hagersten locks)是一种自旋锁,能确保无饥饿性,提

    2024年02月13日
    浏览(32)
  • Java基础:简单工厂模式、工厂方法模式和抽象工厂模式综合概述

    简单工厂模式、工厂方法模式和抽象工厂模式是面向对象设计中用来实现对象创建灵活性的三种不同形式的工厂模式。它们各自有其特点、适用场景及优缺点。以下是它们之间的区别以及对应的适用场景,以及示例说明: 简单工厂模式 定义 : 简单工厂模式提供一个静态方法

    2024年04月25日
    浏览(23)
  • 编程开发8大语言详解,为什么Java是我最推荐的?

    很多没有接触过编程语言的同学,都会觉得编程开发特别高端和神奇,担心理解不了更担心学不会。 当然,也有人会认为,你既然是做编程的,那么你应该什么都会,什么软件的开发都能完成,这是平哥经常听到的两种声音。 在此,平哥需要给大家科普一下, 编程确实改变

    2024年02月05日
    浏览(53)
  • JAVA基础JVM讲解

      主要包括两个子系统和两个组件: Class loader(类装载器) 子系统(用来装载.class文件); Execution engine(执行引擎) 子系统(执行字节码,或者执行本地方法); Runtime data area (运行时数据区域)组件(方法区、堆、java栈、PC寄存器、本地方法栈); Native interface(本地接口)组件。

    2024年02月07日
    浏览(35)
  • JVM——Java虚拟机详解

    JVM——Java虚拟机,它是Java实现平台无关性的基石。 Java程序运行的时候,编译器将Java文件编译成平台无关的Java字节码文件(.class),接下来对应平台JVM对字节码文件进行解释,翻译成对应平台匹配的机器指令并运行。 同时JVM也是一个跨语言的平台,和语言无关,只和class的文

    2024年01月19日
    浏览(67)
  • JVM(Java虚拟机)详解

    目录 一、JVM内存区域划分   1. 什么是内存区域划分以及为啥要进行区域划分   2. JVM内存区域划分详解   3. 堆区详解:    4. 给一段代码,问某个变量是在那个区域上? 二、JVM类加载机制   1.类加载的过程   2. 类加载的时机   3. 双亲委派模型(经典面试) 三、JVM垃圾回收

    2024年02月15日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包