热门标签 | HotTags
当前位置:  开发笔记 > 人工智能 > 正文

Java抽象类原理与用法实例详解

这篇文章主要介绍了Java抽象类原理与用法,结合实例形式详细分析了Java抽象类相关概念、原理、定义、使用方法及操作注意事项,需要的朋友可以参考下

本文实例讲述了Java抽象类原理与用法。分享给大家供大家参考,具体如下:

一、抽象类的基本概念

普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法、普通方法、static方法、常量和变量等内容。而抽象类是指在普通类的结构里面增加抽象方法的组成部分。

那么什么叫抽象方法呢?在所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰

拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明

范例:定义一个抽象类

abstract class A{//定义一个抽象类
    public void fun(){//普通方法
        System.out.println("存在方法体的方法");
    }
    public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}

二、抽象类的使用

我们先看范例。

范例:直接实例化抽象类的对象

package com.wz.abstractdemo;
abstract class A{//定义一个抽象类
    public void fun(){//普通方法
        System.out.println("存在方法体的方法");
    }
    public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
public class TestDemo {
    public static void main(String[] args) {
        A a = new A();
    }
}

运行:

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
        Cannot instantiate the type A
        at com.wz.abstractdemo.TestDemo.main(TestDemo.java:15)

从上可知,A是抽象的,无法直接进行实例化操作。为什么不能直接实例化呢?当一个类实例化之后,就意味着这个对象可以调用类中的属性或者放过了,但在抽象类里存在抽象方法,而抽象方法没有方法体,没有方法体就无法进行调用。既然无法进行方法调用的话,又怎么去产生实例化对象呢。

抽象类的使用原则如下:

(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
(2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;
(3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
(4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。);

范例:

package com.wz.abstractdemo;
abstract class A{//定义一个抽象类
    public void fun(){//普通方法
        System.out.println("存在方法体的方法");
    }
    public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
//单继承
class B extends A{//B类是抽象类的子类,是一个普通类
    @Override
    public void print() {//强制要求覆写
        System.out.println("Hello World !");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        A a = new B();//向上转型
        a.print();//被子类所覆写的过的方法
    }
}

运行结果:

Hello World !

现在就可以清楚的发现:

(1)抽象类继承子类里面有明确的方法覆写要求,而普通类可以有选择性的来决定是否需要覆写;
(2)抽象类实际上就比普通类多了一些抽象方法而已,其他组成部分和普通类完全一样;
(3)普通类对象可以直接实例化,但抽象类的对象必须经过向上转型之后才可以得到。

虽然一个类的子类可以去继承任意的一个普通类,可是从开发的实际要求来讲,普通类尽量不要去继承另外一个普通类,而是去继承抽象类。

三、抽象类的使用限制

(1)抽象类中有构造方法么?

由于抽象类里会存在一些属性,那么抽象类中一定存在构造方法,其存在目的是为了属性的初始化。

并且子类对象实例化的时候,依然满足先执行父类构造,再执行子类构造的顺序。

范例如下:

package com.wz.abstractdemo;
abstract class A{//定义一个抽象类
    public A(){
        System.out.println("*****A类构造方法*****");
    }
    public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
//单继承
class B extends A{//B类是抽象类的子类,是一个普通类
    public B(){
        System.out.println("*****B类构造方法*****");
    }
    @Override
    public void print() {//强制要求覆写
        System.out.println("Hello World !");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        A a = new B();//向上转型
    }
}

执行结果:

*****A类构造方法*****
*****B类构造方法*****

(2)抽象类可以用final声明么?

不能,因为抽象类必须有子类,而final定义的类不能有子类;

(3)抽象类能否使用static声明?

先看一个关于外部抽象类的范例:

package com.wz.abstractdemo;
static abstract class A{//定义一个抽象类
    public abstract void print();
}
class B extends A{
    public void print(){
        System.out.println("**********");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        A a = new B();//向上转型
        a.print();
    }
}

执行结果

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
        Illegal modifier for the class A; only public, abstract & final are permitted
        at com.wz.abstractdemo.A.(TestDemo.java:3)
        at com.wz.abstractdemo.B.(TestDemo.java:9)
        at com.wz.abstractdemo.TestDemo.main(TestDemo.java:18)

再看一个关于内部抽象类:

package com.wz.abstractdemo;
abstract class A{//定义一个抽象类
    static abstract class B{//static定义的内部类属于外部类
        public abstract void print();
    }
}
class C extends A.B{
    public void print(){
        System.out.println("**********");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        A.B ab = new C();//向上转型
        ab.print();
    }
}

执行结果:

**********

由此可见,外部抽象类不允许使用static声明,而内部的抽象类运行使用static声明。使用static声明的内部抽象类相当于一个外部抽象类,继承的时候使用“外部类.内部类”的形式表示类名称。

(4)可以直接调用抽象类中用static声明的方法么?

任何时候,如果要执行类中的static方法的时候,都可以在没有对象的情况下直接调用,对于抽象类也一样。

范例如下:

package com.wz.abstractdemo;
abstract class A{//定义一个抽象类
    public static void print(){
        System.out.println("Hello World !");
    }
}
public class TestDemo {
    public static void main(String[] args) {
        A.print();
    }
}

运行结果:

Hello World !

(5)有时候由于抽象类中只需要一个特定的系统子类操作,所以可以忽略掉外部子类。这样的设计在系统类库中会比较常见,目的是对用户隐藏不需要知道的子类。

范例如下:

package com.wz.abstractdemo;
abstract class A{//定义一个抽象类
    public abstract void print();
    private static class B extends A{//内部抽象类子类
        public void print(){//覆写抽象类的方法
            System.out.println("Hello World !");
        }
    }
    //这个方法不受实例化对象的控制
    public static A getInstance(){
        return new B();
    }
}
public class TestDemo {
    public static void main(String[] args) {
        //此时取得抽象类对象的时候完全不需要知道B类这个子类的存在
        A a = A.getInstance();
        a.print();
    }
}

运行结果:

Hello World !

四、抽象类的应用——模板设计模式

例如,现在有三类事物:

(1)机器人:充电,工作;
(2)人:吃饭,工作,睡觉;
(3)猪:进食,睡觉。

现要求实现一个程序,可以实现三种不同事物的行为。

先定义一个抽象行为类:

package com.wz.abstractdemo;
public abstract class Action{
    public static final int EAT = 1 ;
    public static final int SLEEP = 3 ;
    public static final int WORK = 5 ;
    public abstract void eat();
    public abstract void sleep();
    public abstract void work();
    public void commond(int flags){
     switch(flags){
        case EAT:
            this.eat();
            break;
        case SLEEP:
            this.sleep();
            break;
        case WORK:
            this.work();
            break;
        case EAT + SLEEP:
            this.eat();
            this.sleep();
            break;
        case SLEEP + WORK:
            this.sleep();
            this.work();
            break;
        default:
            break;
        }
    }
}

定义一个机器人的类:

package com.wz.abstractdemo;
public class Robot extends Action{
    @Override
    public void eat() {
        System.out.println("机器人充电");
    }
    @Override
    public void sleep() {
    }
    @Override
    public void work() {
        System.out.println("机器人工作");
    }
}

定义一个人的类:

package com.wz.abstractdemo;
public class Human extends Action{
    @Override
    public void eat() {
        System.out.println("人吃饭");
    }
    @Override
    public void sleep() {
        System.out.println("人睡觉");
    }
    @Override
    public void work() {
        System.out.println("人工作");
    }
}

定义一个猪的类:

package com.wz.abstractdemo;
public class Pig extends Action{
    @Override
    public void eat() {
        System.out.println("猪进食");
    }
    @Override
    public void sleep() {
        System.out.println("猪睡觉");
    }
    @Override
    public void work() {
    }
}

测试主类:

package com.wz.abstractdemo;
public class AbstractDemo {
    public static void main(String[] args) {
        fun(new Robot());
        fun(new Human());
        fun(new Pig());
    }
    public static void fun(Action act){
        act.commond(Action.EAT);
        act.commond(Action.SLEEP);
        act.commond(Action.WORK);
    }
}

运行结果:

机器人充电
机器人工作
人吃饭
人睡觉
人工作
猪进食
猪睡觉

所有的子类如果要想正常的完成操作,必须按照指定的方法进行覆写才可以,而这个时候抽象类所起的功能就是一个类定义模板的功能。

更多java相关内容感兴趣的读者可查看本站专题:《Java面向对象程序设计入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。


推荐阅读
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • 近年来,大数据成为互联网世界的新宠儿,被列入阿里巴巴、谷歌等公司的战略规划中,也在政府报告中频繁提及。据《大数据人才报告》显示,目前全国大数据人才仅46万,未来3-5年将出现高达150万的人才缺口。根据领英报告,数据剖析人才供应指数最低,且跳槽速度最快。中国商业结合会数据剖析专业委员会统计显示,未来中国基础性数据剖析人才缺口将高达1400万。目前BAT企业中,60%以上的招聘职位都是针对大数据人才的。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • qt学习(六)数据库注册用户的实现方法
    本文介绍了在qt学习中实现数据库注册用户的方法,包括登录按钮按下后出现注册页面、账号可用性判断、密码格式判断、邮箱格式判断等步骤。具体实现过程包括UI设计、数据库的创建和各个模块调用数据内容。 ... [详细]
  • “你永远都不知道明天和‘公司的意外’哪个先来。”疫情期间,这是我们最战战兢兢的心情。但是显然,有些人体会不了。这份行业数据,让笔者“柠檬” ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 无线认证设置故障排除方法及注意事项
    本文介绍了解决无线认证设置故障的方法和注意事项,包括检查无线路由器工作状态、关闭手机休眠状态下的网络设置、重启路由器、更改认证类型、恢复出厂设置和手机网络设置等。通过这些方法,可以解决无线认证设置可能出现的问题,确保无线网络正常连接和上网。同时,还提供了一些注意事项,以便用户在进行无线认证设置时能够正确操作。 ... [详细]
  • 本文介绍了游戏开发中的人工智能技术,包括定性行为和非定性行为的分类。定性行为是指特定且可预测的行为,而非定性行为则具有一定程度的不确定性。其中,追逐算法是定性行为的具体实例。 ... [详细]
  • JavaScript设计模式之策略模式(Strategy Pattern)的优势及应用
    本文介绍了JavaScript设计模式之策略模式(Strategy Pattern)的定义和优势,策略模式可以避免代码中的多重判断条件,体现了开放-封闭原则。同时,策略模式的应用可以使系统的算法重复利用,避免复制粘贴。然而,策略模式也会增加策略类的数量,违反最少知识原则,需要了解各种策略类才能更好地应用于业务中。本文还以员工年终奖的计算为例,说明了策略模式的应用场景和实现方式。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 微软小娜企业版发布新版本,提供构建自定义技能的套件
    微软将向企业级市场发布微软小娜企业版的新版本,该版本提供了构建自定义技能的套件,使企业员工可以更方便地使用数字助理。目前该套件仍处于内测期间,只有部分企业可以获得,其他有兴趣的企业需要继续等待。新版本的套件可以帮助员工构建各种自定义技能,如检查休假余额、创建服务凭证等。微软通过让多个开发人员编辑和管理机器人通道注册配置来改善开发者的体验,团队可以自行访问和更改技能注册,满足企业实际需求。微软小娜企业版已经在各个行业得到采用,能够帮助员工专注于优先事项,将非优先处理的任务交给微软小娜处理。 ... [详细]
author-avatar
梦里的天真575
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有