在懂你的人面前,你可以卸下伪装,做最真实的自己,经历的事情越多,
就越发觉身边很少有人能懂你。因为懂得,所以默契,因为懂得,所以安心。
就像那句话说的,人生的每一场相遇,倘若不是幸运,那就是教训。
凡是错误的关系,都是费劲的关系。
大千世界里,每朵花都有每朵花的盛开。
衰败每个人都有,每个人的欢喜与落寞,而懂得永远比爱更慈悲。
请相信,在这个世间行走,遇见无数的人,唯有三观相合才可以一起走到最后。
—————————————— 一禅心灵庙语
文章目录
- Java —— 抽象类、接口,你不知道的都在这里 ! !
- 每博一文案
- 抽象类
- 接口
- 最后:
抽象类
- 子类在继承父类的过程中,会继承父类的一些方法,如果不能确定子类类型到底该如何实现,可以先将父类中的方法定义为 抽象类 ,当子类继承时再进行具象化。
- 抽象类的定义使用关键字 :abstract 格式如下:
abstract class Shapes {
}
- 抽象方法 ,抽象方法是没有主体的,不可以加上 { } 的代码块,
- 抽象方法是存在于抽象类里面的,只要包含一个抽象方法,该类就必须是抽象类
- 抽象方法的定义 :格式如下:
abstract void draw(); // 注意不可以有主体,抽象方法
- 抽象类 是不可以被实例化的,会出错的
abstract class Shapes {
abstract void draw();
}
public class Blog06 {
public static void main(String[] args) {
Shapes shapes = new Shapes();
}
}
运行结果
- 抽象类中可以有 普通的方法和字段
abstract class Shapes {
protected String name;
public void pint() {
}
abstract void draw();
}
- 抽象类主要就是用来继承的,通过继承的方式,实例化子类,通过子类调用,重写的构造方法 向上转型
- 如果一个类继承了,这个抽象类,那么这个类必须重写抽象类当中的所有抽象方法
- 当抽象类 A 继承了抽象类 B ,那么 A 可以不用重写 B 抽象类中的抽象方法,因为 A自己也是抽象类,但是一旦继承的不是 抽象类,那么就一定需要重写该 继承中抽象类中的所有抽象方法
- 注意 无论是 抽象类 还是 抽象方法 都不可以 被 final 修饰,因为被 final(最后,无法改变) 修饰的类是无法被继承了,final 修饰的抽象方法是无法被重写的,
- 非抽象方法 可以调用 抽象方法的
final abstract class Shapes { // 抽象类不可以被 final 修饰无法被,继承的
protected String name;
public void pint() {
}
abstract void draw();
}
public class Blog06 {
public static void main(String[] args) {
}
}
运行错误结果
abstract class Shapes {
protected String name;
public void pint() {
}
abstract final void draw(); // 抽象方法,不可以被 final 修饰,修饰了无法重写该抽象方法
}
class Circle extends Shapes {
@Override // 重写,注解 错误提醒功能,人和编译器都可以读懂的注释
public final void draw() {
System.out.println("画一个 ");
}
}
public class Blog06 {
public static void main(String[] args) {
}
}
运行错误结果
- 抽象类实例:
abstract class Shapes {
protected String name;
public void pint() {
}
abstract void draw(); // 抽象方法,不可以被 final 修饰,修饰了无法重写该抽象方法
}
class Circle extends Shapes {
@Override // 重写,注解 错误提醒功能,人和编译器都可以读懂的注释
public final void draw() {
System.out.println("画一个 ");
}
}
class Stars extends Shapes {
@Override
public final void draw() {
System.out.println("画一个 ");
}
}
public class Blog06 {
public static void func(Shapes shapes) {
shapes.draw();
}
public static void main(String[] args) {
Shapes shapes = new Circle();
Shapes shapes1 = new Stars();
func(shapes);
func(shapes1);
}
}
运行结果:
- 抽象类本身是不能被实例化,要想使用,只能创建该抽象类的子类,然后让子类重写抽象类中的抽象方法
- 有些人会有这样的想法:普通的类也是可以被继承呀,普通的方法也是可以被重写的,为啥子非得用这么复杂的抽象类和抽象方法呢
- 确实如此,但是使用抽象类相当于多了一重编译器的校验,使用抽象类的场景就如同上面的实例代码一样,实际工作不应该由父类完成,而是应由子类完成,那么此时如果不小心误用父类了,使用普通类,编译器是不会报错的,但是父类是抽象类就会实例化的时候,就会提示错误,让我们尽早发现问题尽早处理问题
- 事实上,很多语法存在的意义,都是为了预防出 “出错” ,例如我们长常用的 final 也是类似的,创建的变量用户不去修改,不就相当于是常量吗? 但是 加上了 final 能够在不小心修改的时候,让编译器及时提醒我们
接口
- 接口和类是并列的关系,都属于引用数据类型的一种,类的定义使用关键字 class ,接口的定义使用关键字 interface 。接口用来定义一种能力,某个类型要具备接口提供的能力,就要实现这个接口。
- 接口的定义:如下:
interface IFlying { // 接口的定义
void fly(); // 抽象方法
}
-
在 JDK1.8 之前,接口中只有两部分内容:
- 常量 :固定默认修饰符为 :public static final , 可以省略不写
- 声明中带有 static 的类变量可以通过 **“类名.字段名” ** 进行访问,与此相同的,接口中的常量可以通过 “接口名.字段名” 进行访问
- 抽象方法 : 固定默认修饰符为:public abstract ,可以省略不写
-
在 JDK1.8 之后,新增了如下非抽象方法:
- 被 public default 修饰的非抽象方法
- 静态方法
-
接口是不可以实例化的,而是通过继承实现接口:
interface IFlying { // 接口的定义
void fly(); // 抽象方法
}
public class Blog06 {
public static void main(String[] args) {
IFlying iFlying = new IFlying();
}
}
错误运行结果
- 接口和类之间的关系,implements(实现接口的意思) 因为接口中的方法是抽象方法,所以在实现上是要对抽象方法进行重写的
- 注意 接口中的对重写的抽象方法 的 权限修饰符 必须是 public ,因为接口中的抽象方法默认是 public abstract 的,根据重写的规则:子类中的权限修饰符必须 **>= ** 父类中的权限修饰符,而 public 是最大的,所以我们只能用相等的 public 修饰了
- 接口的实现使用关键字 :implements
- 当类的声明中同时存在 extends(继承) 和 implements(接口的实现) 时,一定要先书写 extends(继承) ,再写 implements(接口的实现)
class Zoon {
}
interface IFlying { // 接口的定义
void fly(); // 抽象方法
}
class Brids extends Zoon implements IFlying {
@Override
public void fly() { // 注意重写接口中的抽象方法 ,必须是 public 的权限修饰符,
}
}
- 为了解决 Java 中单继承的问题,可以实现多个接口,使用 逗号 分隔别个 接口 ,一个类实现了多个接口就需要重写 所有接口的 抽象方法
- 只要这个类,实现了接口,那么你就可以进行 向上转型了
class Zoon {
protected String name;
public Zoon(String name) {
this.name = name;
}
}
interface IRuning { // 接口的定义
void run(); // 接口中的抽象类
}
interface ISwimming { // 接口的定义
void swim(); // 接口中的抽象类
}
// 多个接口的实现,逗号分隔
class Frog extends Zoon implements IRuning,ISwimming { // IRuning,ISwimming 接口的实现
public Frog(String name) {
super(name);
}
@Override
public void run() {
System.out.println(super.name+" 可以跑的飞快");
}
@Override
public void swim() {
System.out.println(super.name+" 可以游得飞快");
}
}
- 我们通过接口类型的变量可以引用实现该接口的类类型的实例。只有实现了对应接口才可以调用 该接口中的抽象方法的重写
- 多接口,接口的使用实例:
class Zoon {
protected String name;
public Zoon(String name) {
this.name = name;
}
}
interface IFlying { // 接口的定义
void fly(); // 抽象方法
}
interface IRuning { // 接口的定义
void run(); // 接口中的抽象类
}
interface ISwimming { // 接口的定义
void swim(); // 接口中的抽象类
}
class Brids extends Zoon implements IFlying { // 继承 IFlying接口的实现
public Brids(String name) {
super(name); // 调用父类的构造方法,第一行
}
@Override
public void fly() { // 注意重写接口中的抽象方法 ,必须是 public 的权限修饰符,
System.out.println(super.name+ " 可以飞的飞快");
}
}
class Fish extends Zoon implements ISwimming { // ISwimming 接口的实现
public Fish(String name) {
super(name);
}
@Override
public void swim() {
System.out.println(super.name+" 可以游的飞快");
}
}
class Cats extends Zoon implements IRuning { // IRuning 接口的实现
public Cats(String name) {
super(name);
}
@Override
public void run() {
System.out.println(super.name+" 可以跑的飞快");
}
}
class Frog extends Zoon implements IRuning,ISwimming { // IRuning,ISwimming 接口的实现
public Frog(String name) {
super(name);
}
@Override
public void run() {
System.out.println(super.name+" 可以跑的飞快");
}
@Override
public void swim() {
System.out.println(super.name+" 可以游得飞快");
}
}
public class Blog06 {
public static void main(String[] args) {
IRuning iRuning = new Cats("年轻的猫"); // 定义 IRuning 接口类型,访问接口的抽象方法 run()
iRuning.run();
IFlying iFlying = new Brids("年轻的鸟");// 定义 IFlying 接口类型,访问接口的抽象方法 fly()
iFlying.fly();
Frog frog = new Frog("年轻的青蛙");// 实例化子类,访问子类中的方法
frog.run();
frog.swim();
}
运行结果
- 上面的代码展示了 Java 面向对象编程中最常见的用法: 一个类继承一个父类, 同时实现多种接口.
- 这样设计有什么好处呢? 时刻牢记 多态 的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力
最后:
限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵 —— 多多指教,谢谢大家,后会有期,江湖再见!



