Java 学习记录 第十二天

由于本渣渣是前端转行Java,所以编辑器的选择就直接用 webstorm 同公司的 idea
接下来的知识梳理有一部分会借鉴大佬 廖雪峰的博客

学习目标

结合抽象类对多态进一步的理解;实例分析(类、抽象类、接口)之间的区别。


学习内容

  • 抽象类的概念
  • 实例解析继承抽象类
  • 抽象方法的声明与使用
  • 抽象类的总结以及规定
  • Java封装的概念
  • Java接口的含义
  • 标记接口

抽象类的概念

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。
在Java语言中使用abstract class来定义抽象类。

public abstract class Hero {private String name;private Integer hp;private Integer mp;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getHp() {return mp;}public void setHp(Integer hp) {this.hp = hp;}public Integer getMp() {return mp;}public void setMp(Integer mp) {this.mp = mp;}public Hero(String name) {setName(name);System.out.println("创建英雄:" + getName());}
}public class Test1 {public static void main(String[] args) {Hero hero1 = new Hero("后羿") {@Overridepublic String getName() {return super.getName();}};Hero hero2 = new Hero("后羿");}
}

上述的 hero1 和 hero2 都同样是引用了 抽象类 Hero 在实例化的阶段,这两种写法会产生不一样的结果。

  • hero1 可以正常编译,然而 hero2 会产生编译报错。
  • 为什么 hero1 可以正常编译呢?其实这种写法等同于隐式的声明了一个继承类,因为我们重写了抽象类的方法,产生了多态的现象,jvm虚拟机就会执行继承类的构造器来实例化对象。
  • 那 hero2 无法实例化就是正常现象了,总结下原因就是 抽象类哪怕声明了构造器,也无法直接实例化对象。

上述代码的运行结果如下:

实例解析继承抽象类

根据上述的实例分析,我们已经知道了抽象类的一些概念,下面再通过一个正常的示例来演示下抽象类的继承与实例化。

public abstract class Hero {// .....省略代码,同上public Hero(String name, Integer hp, Integer mp) {setName(name);setHp(hp);setMp(mp);System.out.println("创建英雄:" + getName()  + ",血量:" + getHp() + ",蓝量:" + getMp());}
}public class Houyi extends Hero {private String equip;public void setEquip(String equip) {this.equip = equip;}public String getEquip() {return equip;}public Houyi(String equip) {super("后羿", 3000, 1500);setEquip(equip);}
}public class Test1 {public static void main(String[] args) {Houyi houyi = new Houyi("复活甲");System.out.println(houyi.getName() + " 一波超神,瞬间买了 " + houyi.getEquip());}
}

简单的分析下上述代码,Hero 类 是一个抽象类,Houyi 类 则是继承了 Hero 抽象类 的具体实现类,最后实例化的时候用 Houyi 类 的构造器来实例化对象,输出结果如下:

抽象方法的声明与使用

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。
Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。
抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

public abstract class Hero {// ...省略代码// 声明抽象方法public abstract void payEquip(String equip);// ...省略代码
}public class Houyi extends Hero {// ...省略代码@Overridepublic void payEquip(String equip) {System.out.println(getName() + "购买了装备:" + equip);setEquip(equip);}// ...省略代码
}public class Test1 {public static void main(String[] args) {Houyi houyi = new Houyi();houyi.payEquip("复活甲");Hero houyi2 = new Houyi();houyi2.payEquip("破晓");}
}

声明抽象方法会造成以下两个结果:

  1. 如果一个类包含抽象方法,那么该类必须是抽象类。
  2. 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

上述代码因为 Hero抽象类 也声明了抽象方法 payEquip(),所以在实例化对象引用类型也可以用 Hero抽象类,那么 houyi2 调用的 payEquip() 方法其实指向的是 Houyi类 的具体实现,这其实也是 一种多态的现象。

输出结果如下:

抽象类的总结以及规定

  1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
  2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
  4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
  5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

Java封装的概念

在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
封装的优点:

  1. 良好的封装能够减少耦合。
  2. 类内部的结构可以自由修改。
  3. 可以对成员变量进行更精确的控制。
  4. 隐藏信息,实现细节。

Java接口的含义

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类相似点:

  1. 一个接口可以有多个方法。
  2. 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
  3. 接口的字节码文件保存在 .class 结尾的文件中。
  4. 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

  1. 接口不能用于实例化对象。
  2. 接口没有构造方法。
  3. 接口中所有的方法必须是抽象方法。
  4. 接口不能包含成员变量,除了 static 和 final 变量。
  5. 接口不是被类继承了,而是要被类实现。
  6. 接口支持多继承。

接口特性:

  1. 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
  2. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
  3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

抽象类和接口的区别:

  1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
  2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
  3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
  4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

注意 JDK 版本的区别:

  1. JDK 1.8 以后,接口里可以有静态方法和方法体了。
  2. JDK 1.8 以后,接口允许包含具体实现的方法,该方法称为"默认方法",默认方法使用 default 关键字修饰。
  3. JDK 1.9 以后,允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去。
public interface Skill {public static final String PassiveSkill = "被动技能:";public static final String ActiveSkill = "主动技能:";public void LearnSill(String skill, String hero);
}public class Chengjiesheji implements Skill{public void LearnSill(String skill, String hero) {System.out.println(hero + " 学习了 " + Skill.PassiveSkill + skill);}public Chengjiesheji() {Hero houyi = new Houyi();LearnSill("惩戒射击", houyi.getName());}
}public class Test2 {public static void main(String[] args) {Chengjiesheji c = new Chengjiesheji();}
}

上述代码简单演示了一下接口的声明到实现的过程,输出如下:

接口有以下特性:

  1. 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  2. 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
  3. 接口中的方法都是公有的。

接口的实现需要注意的是,当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类;类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
重写接口中声明的方法时,需要注意以下规则:

  1. 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
  2. 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
  3. 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。

在实现接口的时候,也要注意一些规则:

  1. 一个类可以同时实现多个接口。
  2. 一个类只能继承一个类,但是能实现多个接口。
  3. 一个接口能继承另一个接口,这和类之间的继承比较相似。
  • 接口的继承: 一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
  • 接口的多继承: 在Java中,类的多继承是不合法,但接口允许多继承。

标记接口

最常用的继承接口是没有包含任何方法的接口。
标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。
标记接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。

  • 建立一个公共的父接口: 正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。
  • 向一个类添加数据类型: 这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

自学不易,点赞鼓励。

谢谢各位看官,如果有哪里写错的还望指出来哈,共同进步。

抽象类、抽象方法、封装的概念、接口的含义(Java 从自学到就业 第12天)相关推荐

  1. Java:抽象方法和抽象类,抽象类应用模板方法模式,接口及使用

    一.抽象类概念和作用 抽象类                 Java中可以定义没有方法体的方法,该方法由子类来具体实现.                 该没有方法体的方法我们称之为抽象方法,含有抽 ...

  2. java接口抽象方法_Java 接口 抽象类 抽象方法

    abstract class elehousekeeping { //抽象家用电器类 abstract void opermode(); //抽象方法 } class TV extends eleho ...

  3. 一文总结:抽象类(abstract)与接口(interface)的特点和代码展示

    文章目录 1. 什么是抽象类? 2. 抽象类与抽象方法的特点 3. 抽象类的应用 4. 什么是接口? 5.接口的特点 6.接口面试题 7.抽象类与接口的对比 本篇文章已同步到:https://www. ...

  4. (十)Core Java 面向对象(封装,继承,多态,接口) -02 (96)

     目录 :        24 ). 面向对象(聚集关系) 25 ). 面向对象(子父类中变量的特点) 26 ). 面向对象(子父类中函数的特点-覆盖) 27 ).  面向对象(子父类中构造函数的特点 ...

  5. 抽象类,模版模式和接口

    抽象类,模版模式和接口 抽象类 抽象类的特点 抽象类不可以被实例化 什么时候使用抽象类 抽象类和普通类的区别 抽象类的作用 模板模式 什么是模板模式 何时使用 优点 缺点 分析 类和类之间的耦合问题 ...

  6. java 接口封装_Java-封装 接口

    Java 封装 封装是指一种将抽象性函式接口的实现细节部分包装.隐藏起来的方法 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问 要访问该类的代码和数据,必须通过严格的接口 ...

  7. IEnumeratorTItem和IEnumerator Java 抽象类和普通类、接口的区别——看完你就顿悟了...

    IEnumerable 其原型至少可以说有15年历史,或者更长,它是通过 IEnumerator 来定义的,而后者中使用装箱的 object 方式来定义,也就是弱类型的.弱类型不但会有性能问题,最主要 ...

  8. JAVA SE、EE、ME,JRE、JDK,基本数据类型,访问修饰符、函数、封装的概念、UML类图、构造方法、this关键字、static关键字、方法重载、方法重写、包(packahe)

    运行第一个JAVA程序: 这里使用的开发环境是eclipse,新建一个java工程,然后可以看到src这个是存放java代码的地方,然后在src文件右击新建一个class(类),然后可以看到下图,同样 ...

  9. 抽象类(Abstract)和接口的不同点、共同点(Interface)。

    同样点: (1) 都能够被继承 (2) 都不能被实例化 (3) 都能够包括方法声明 (4) 派生类必须实现未实现的方法 区 别: (1) 抽象基类能够定义字段.属性.方法实现.接口仅仅能定义属性.索引 ...

最新文章

  1. 【直播课】TensorRT工程落地实践:快速掌握模型优化部署
  2. 如何在私有链部署智能合约
  3. 云计算机室局域网时通时断,为什么网上邻居时通时断?
  4. 2019ICPC南京网络赛A题 The beautiful values of the palace(三维偏序)
  5. micropython oled中文_micropython中怎么将gb2312编码的字节流变成中文
  6. 存储端显示主机链路降级_【计算机网络】你真的理解数据链路层吗?
  7. linux让新生成的文件自动加锁,Linux_实用技巧一则 Linux系统对文件进行加锁,当有多个工作线程要同时对一 - phpStudy...
  8. 白话用consul作为注册中心搭建微服务
  9. linux mysql show_Linux下 MySQL Show命令的使用
  10. 2010年软考 考试日期安排
  11. RS485自动切换电路:数据收发原理
  12. java 图片 文字居中_完美实现文字图片水平垂直居中
  13. c语言中指针几个字节,【C++】一个指针占几个字节?为什么呢?
  14. 自己对ajax的第一次上手被人说菜死还真是菜
  15. 我在上海奋斗的五年---从月薪3500到700万(读后感:一个真汉子的人生)
  16. 多节点+内核文件接口
  17. laravel 5.6入门
  18. Qt案例1-extending-qml
  19. 编译GPU版本Matconvnet
  20. 美文欣赏-------小石潭记

热门文章

  1. HTML中a标签的作用
  2. JavaPoet开源项目的使用
  3. CANoe-CAN通信
  4. Python_一元线性回归及回归显著性
  5. 【jsPlumb】使用记录
  6. Dom获取 属性操作
  7. Win10+vs2017跑yolov3
  8. elementUI中el-upload上传文件时附带额外参数传递
  9. SQL到底该怎么发音: S-Q-L or Sequel?
  10. Gazebo机器人仿真