-
2019-03-08 20:39:50
抽象类和接口都包含类可以由子类继承实现的成员,但抽象类是对根源的抽象,而接口上是对动作的抽象。抽象类的功能要远超过接口,那为什么还要使用接口呢?这主要是由于定义抽象类的代价高(因为每个类只能继承一个类,在这个类中,必须继承或者编写出其子类的所有共性),因此,虽然接口在功能上会弱化很多,但它只是针对一个动作的描述,而且可以在一个类中同时实现多个接口,这样会降低设计阶段的难度。
抽象类和接口的区别主要有以下几点:
- 子类只能继承一个抽象类,但可以实现多个接口
- 一个类实现一个接口必须实现接口中的所有方法,但抽象类不用
- 抽象类中的成员变量可以是任意类型的,而接口中的成员变量只能是public static final
- 接口中只能定义抽象方法,而抽象类中可以定义 非抽象方法
- 抽象类中可以由静态方法和静态代码块,而接口中不可以
- 接口不可以被实例化,没有构造方法,但抽象类可以有构造方法
更多相关内容 -
Java中抽象类和接口的区别
2019-02-07 14:10:07在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。这两者有太多相似的地方,又有太多不同的地方。很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然。今天我们就一起来学习一下Java中的接口...对于面向对象编程来说,抽象是它的一大特征之一。在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。这两者有太多相似的地方,又有太多不同的地方。很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然。今天我们就一起来学习一下Java中的接口和抽象类。
一、抽象类
在了解抽象类之前,先来了解一下抽象方法。抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。抽象方法的声明格式为:
abstract void fun();
抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。
下面要注意一个问题:在《JAVA编程思想》一书中,将抽象类定义为“包含抽象方法的类”,但是后面发现如果一个类不包含抽象方法,只是用abstract修饰的话也是抽象类。也就是说抽象类不一定必须含有抽象方法。个人觉得这个属于钻牛角尖的问题吧,因为如果一个抽象类不包含任何抽象方法,为何还要设计为抽象类?所以暂且记住这个概念吧,不必去深究为什么。
[public] abstract class ClassName { abstract void fun(); }
从这里可以看出,抽象类就是为了继承而存在的,如果你定义了一个抽象类,却不去继承它,那么等于白白创建了这个抽象类,因为你不能用它来做任何事情。对于一个父类,如果它的某个方法在父类中实现出来没有任何意义,必须根据子类的实际需求来进行不同的实现,那么就可以将这个方法声明为abstract方法,此时这个类也就成为abstract类了。
包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可以拥有成员变量和普通的成员方法。注意,抽象类和普通类的主要有三点区别:
- 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
- 抽象类不能用来创建对象;
- 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
在其他方面,抽象类和普通的类并没有区别。
二、接口
接口,英文称作interface,在软件工程中,接口泛指供别人调用的方法或者函数。从这里,我们可以体会到Java语言设计者的初衷,它是对行为的抽象。在Java中,定一个接口的形式如下:
[public] interface InterfaceName { }
接口中可以含有 变量和方法。但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误),并且接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法。从这里可以隐约看出接口和抽象类的区别,接口是一种极度抽象的类型,它比抽象类更加“抽象”,并且一般情况下不在接口中定义变量。
要让一个类遵循某组特地的接口需要使用implements关键字,具体格式如下:
class ClassName implements Interface1,Interface2,[....]{ }
可以看出,允许一个类遵循多个特定的接口。如果一个非抽象类遵循了某个接口,就必须实现该接口中的所有方法。对于遵循某个接口的抽象类,可以不实现该接口中的抽象方法。
三、抽象类和接口的区别
1.语法层面上的区别
- 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
- 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
2.设计层面上的区别
1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。
2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。
下面看一个网上流传最广泛的例子:门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:
abstract class Door { public abstract void open(); public abstract void close(); }
或者:
interface Door { public abstract void open(); public abstract void close(); }
但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:
1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能;
2)将这三个功能都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。
从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。
interface Alram { void alarm(); } abstract class Door { void open(); void close(); } class AlarmDoor extends Door implements Alarm { void oepn() { //.... } void close() { //.... } void alarm() { //.... } }
最后再用一个表格的形式来总结一下抽象类和接口的区别:
参数 抽象类 接口 默认的方法实现 它可以有默认的方法实现 接口完全是抽象的。它根本不存在方法的实现 实现 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现 构造器 抽象类可以有构造器 接口不能有构造器 与正常Java类的区别 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 接口是完全不同的类型 访问修饰符 抽象方法可以有public、protected和default这些修饰符 接口方法默认修饰符是public。你不可以使用其它修饰符。 main方法 抽象方法可以有main方法并且我们可以运行它 接口没有main方法,因此我们不能运行它。 多继承 抽象方法可以继承一个类和实现多个接口 接口只可以继承一个或多个其它接口 速度 它比接口速度要快 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。 添加新方法 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 如果你往接口中添加方法,那么你必须改变实现该接口的类。 我有一个微信公众号,经常会分享一些Java技术相关的干货;如果你喜欢我的分享,可以用微信搜索“Java团长”或者“javatuanzhang”关注。
-
Java中抽象类和接口的区别_动力节点Java学院整理
2020-08-30 17:39:04java抽象类和接口最本质的区别是接口里不能实现方法--接口中的方法全是抽象方法。抽象类中可实现方法--抽象类中的方法可以不是抽象方法,下文给大家简单介绍下,需要的的朋友参考下 -
Java 抽象类和接口的区别
2022-03-15 20:06:50接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法; 一个类只能继承一个抽象类,而一个类却可以实现多个接口。 二、设计层面上的区别 a.抽象类是对一种事务的抽象,是对整个类进行...一、语法层面上的区别
- 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract (隐式声明)方法;
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final(隐式声明)类型的(必须在声明时赋值);
- 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
二、设计层面上的区别
a. 抽象类是对一种事务的抽象,是对整个类进行抽象,包括属性,行为(方法)。接口是对行为(行为)的抽象。如果一个类继承或实现了某个抽象类,那么一定是抽象类的种类(拥有同一种属性或行为的类)。
b. 设计层面不同,抽象类作为很多子类的父类,是一种模板设计,而接口是一种规范,它是一种辐射式设计,也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象方法中添加实现,子类可以不用变更,而对于接口不行,如果接口进行了变更,那么实现它的类都需要做变更。
三、示例
- java接口的修饰符:abstract(默认不写。interface本身就是抽象的,加不加abstract都一样)
- 接口中字段的修饰符:public static final(默认不写)
解释如下:
- public: 使接口的实现类可以使用该常量;
- static:接口不涉及和任何具体实例相关的细节,因此接口没有构造方法,不能被实例化,没有实例变量,只有静态变量。(static修饰就表示它属于类的,随的类的加载而存在的,当JVM把字节码加载进JVM的时候,static修饰的成员已经在内存中存在了。如果是非static的话,就表示属于对象的,只有建立对象时才有它,而接口是不能建立对象的,所以接口的常量必须定义为static。)
- final:接口中不可以定义变量,即定义的变量前都要加上final修饰,使之成为常量,且必须赋初始值!(final修饰就是保证接口定义的常量不能被实现类去修改,如果没有final的话,由子类随意去修改的话,接口建立这个常量就没有意义了。
- 接口中方法的修饰符:public abstract(默认不写)
接口方法仅仅描述方法能做什么,但是不指定如何去做,所以接口中的方法都是抽象的(abstract方法)
四、注意
1 接口和抽象类分别在什么时候使用
a. 如果拥有一些方法,并想让他们中的一些有默认的具体实现,请选择抽象类
b. 如果想实现多重继承,那么请使用接口,由于java不支持多继承,子类不能继承多个类,但一个类可以实现多个接口,因此可以使用接口来解决。
c. 如果基本功能在不断变化,那么就使用抽象类,如果使用接口,那么每次变更都需要相应的去改变实现该接口的所有类。
2 JDK8中接口的默认方法和静态方法
JDK8中,Oracle引入默认方法和静态方法,用来减少抽象类和接口的差异,可以在接口中提供默认的实现方法并实现该接口的类不用强制去实现这个方法。JDK8中接口的静态方法只能通过接口名直接去调用,接口中的默认方法因为不是abstract的,所以可重写,也可以不重写。
3 优先级问题
当一个类,既继承了一个父类,又实现多个接口,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法
4 接口的继承
一个接口能继承另外一个或者多个接口,这和类之间的继承比较相似,接口的继承使用extends关键字,子接口继承父接口的方法.如果父接口中的默认方法有重名的,那么子接口需要重写一次
5 默认方法
使用default修饰,不可省略,供子类调用或者子类重写
可以继承,可以重写,二选一,但是只能通过实现类的对象来调用
接口中,有多个默认方法时,实现类都可继承使用,如果继承方法有重名的,必须重写一次
6 其他
1.接口中无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰
2.接口中,没有构造方法,不能创建对象
3.接口中,没有静态代码块
-
Java中的抽象类和接口
2022-04-08 15:17:42各位铁汁们大家好呀!今天让我们继续学习java,看看java中的抽象类和接口到底是什么? 里面也会讲到多态呀,一起来看看吧目录
各位铁汁们大家好呀😊!
😎今天让我们继续学习java,看看java中的抽象类和接口到底是什么🤔?
什么是抽象类
🍑我们之前学过什么是类,那么抽象类是不是也是类的一种呢?
听名字就感觉好抽象呀!说对了,他就是抽象的,不是具体的。在类中没有包含足够的信息来描绘一个具体的对象,这样的类称为抽象类。
🌰来看一个抽象类的例子
// 抽象类和抽象方法需要被 abstract 关键字修饰 abstract class Shape { // 抽象类中的方法一般要求都是抽象方法,抽象方法没有方法体 abstract void draw(); }
大家觉得这个抽象类是不是什么也没干,他唯一的方法draw()还是空的。
像这样的类是不是就没有包含足够的信息来描绘一个具体的对象,自然也就不能实例化对象了。不信你看:
🍑那既然一个类不能实例化,那这种抽象类存在的意义是什么呀🤔?别急,存在即合理,听我慢慢道来。
抽象类在实现多态中的意义
🍑抽象类存在的一个最大意义就是被继承,当被继承后就可以利用抽象类实现多态。
来看一段代码
// 抽象类和抽象方法需要被 abstract 关键字修饰 abstract class Shape { // 抽象类中的方法一般要求都是抽象方法,抽象方法没有方法体 abstract void draw(); } // 当一个普通类继承一个抽象类后,这个普通类必须重写抽象类中的方法 class Cycle extends Shape { @Override void draw() { // 重写抽象类中的draw方法 System.out.println("画一个圆圈"); } } public class Test4 { public static void main(String[] args) { //Shape shape = new Shape(); 抽象类虽然不能直接实例化 // 但可以把一个普通类对象传给一个抽象类的引用呀,即父类引用指向子类对象 Shape shape = new Cycle(); // 这称作:向上转型 /*Cycle cycle = new Cycle(); Shape shape = cycle // 这是向上转型的另一种写法 */ shape.draw(); // 通过父类引用调用被子类重写的方法 } }
运行之后你就会发现神奇的一幕:
大家在看完了代码可能会有很多疑问,别急咱们一个一个的说,
📝什么是向上转型:一句话总结就是“父类引用指向子类对象”
向上转型后的变化
- 🏀关于方法:父类引用可以调用子类和父类公用的方法(如果子类重写了父类的方法,则调用子类的方法),但子类特有的方法无法调用。
- 🏀关于属性: 父类引用可以调用父类的属性,不可以调用子类的属性
向上转型的作用
- 🐟减少一些重复性的代码
- 🐟对象实例化的时候可以根据不同需求实例化不同的对象
🌰这样的话就我们上面的代码就可以理解了
📝看来,我们可以通过子类对抽象类的继承和重写,抽象类还真有点用呀!
🍑但这和多态有什么关系呢,抽象类用起来这么麻烦,我还不如直接用普通类,也能达到这样的效果,还不用再写一个子类呢😫?
🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟
🌰那行,你再看看下面的代码,你就知道抽象类在实现多态时的好处了。
abstract class Shape { public abstract void draw(); // 抽象方法不能里有具体的语句 } // 当一个普通类继承一个抽象类的时候,再这个子类中必须重写抽象类中的抽象方法 class Cycle extends Shape { @Override // 如果不重写会报错,但如果继承的是普通类则不会报错,用抽象类更安全 public void draw() { System.out.println("画一个圆圈"); } } class Flower extends Shape { // 不同的子类对父类的draw方法进行了不同的重写 @Override public void draw() { System.out.println("画一朵花"); } } class Square extends Shape { @Override public void draw() { System.out.println("画一个正方形"); } } public class Test4 { public static void main(String[] args) { Cycle cycle = new Cycle(); // 子类引用cycle Flower flower = new Flower(); // 子类引用flower Square square = new Square(); // 数组的类型是Shape,即数组中每一个元素都是一个父类引用 // 在这个过程其实也发生了向上转型,对抽象类中的方法进行了重写 Shape[] shapes = {cycle, flower, square}; // 父类引用引用不同的子类对象 for (int i = 0; i < shapes.length; i++) { Shape shape = shapes[i]; // 父类引用shape指向—>当前所对应的子类对象 shape.draw(); // 通过父类引用调用子类重写的draw方法 } } }
🍑调用同一个方法竟然打印出了不同的结果😮,这难道就是所谓的多态🤔
是不是有点懵😂,下面我们来解释一下😉
// 对上面的代码补充一下 // 可能你对 Shape[] shapes = {cycle, flower, square};不太理解 // 但上面的代码就相当于 Shape[] shapes1 = new Shape[3]; // 有三个不同的子类对象呀!数组大小为3 // (将指向->子类对象)的子类引用赋值给父类对象,不就相当于该夫类引用指向->所对应的子类对象吗 //这是向上转型的另一种写法,应为前面已经实例化了子类对象 Cycle cycle = new Cycle(); shapes1[0] = cycle; // 如果前面没实例化子类对象,就要写成shape1[0] = new Cycle shapes1[1] = flower; shapes1[2] = square;
对于多态来说,他有这三个要素
- 继承(我们刚才的Cycle类继承Shape抽象类)
- 重写(我们子类对draw方法的重写)
- 父类指向子类对象(就是shape1[0] = cycle -->也可以称作向上转型)
🍑回头再看一下我们的代码,是不是就刚好符合了多态的三要素😉。
📝当我们的父类引用指向不同的子类对象时,当我们调用同一个draw方法时却输出了不同的结果。(其实就是该方法再子类中被重写成了不同形式)这就叫做多态 。
嘻嘻😂,其实只要只要结合着例子来看,多态也没那么难理解呀😎
🍑那为啥一定要用抽象类呢😂?我一个普通类继承普通类来实现多态不可以吗🤔
🌰当然可以,但不太安全有风险;
但如果是抽象类的话,就不一样了😉
🍑从这我们也可以看出,当用抽象类的时候,编译器自动就对我们是否重写进行了校验,而充分利用编译器的校验, 在实际开发中是非常有意义的 。所以说抽象类还是有用的,嘻嘻😉
📝好了,相信到这里你对抽象类也有了一个大概的认识😊,下面我们来简单做一下总结
- 使用abstract修饰的类或方法,就抽象类或者抽象方法
- 抽象类是不能具体的描述一个对象,不能用抽象类直接实例化对象
- 抽象类里面的成员变量和成员方法,都是和普通类一样的,只不过就是不能进行实例化了
- 当一个普通类继承这个抽象类后,那么这个普通类必须重写抽象类当中的所有的抽象方法🤔(我们之前说过抽象类是不具体的,没有包含足够的信息来描述一个对象,所以我们需要把他补充完整)
- 但当一个抽象类A继承了抽象类B,这是抽象类A就可以不重写抽象类B当中的抽象方法
- final不能修饰抽象类和抽象方法(因为抽象类存在的最大意义就是被继承,而被final修饰的不能被继承,final和抽象,他们两个是天敌😂)
- 抽象方法不能被private修饰(抽象方法一般都是要被重写的,你被private修饰了,还怎么重写😫)
- 抽象类当中不一定有抽象方法,但如果一个类中有抽象方法,那么这个类一定是抽象类。
🌰哈哈,上面的8条总结是不是臭长臭长的,大家也不用专门去记(用的多了,自然就记住了😉)
🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟
接口是什么
🍑抽象类是从多个类中抽象出来的模板,如果将这种抽象进行的更彻底,则可以提炼出一种更加特殊的“抽象类”——接口(Interface)🤔。
📝接口是Java中最重要的概念之一,它可以被理解为一种特殊的类,不同的是接口的成员没有执行体,是由全局常量和公共的抽象方法所组成😎。
如何定义一个接口呢?下面我们来看一个栗子🌰
//接口的定义格式与定义类的格式基本相同,将class关键字换成 interface 关键字,就定义了一个接口 public interface 接口名称{ // 定义变量 int a = 10; // 接口当中的成员变量默认都是public static final // 抽象方法 public abstract void method1(); // public abstract 是固定搭配,可以不写 void method2(); // 接口当中的成员方法默认都是public abstract, 更推荐用第二种来定义方法 }
可以看到接口和类其实还是有很多相似点:
📝接口中也包含抽象方法,所以也不能直接实例化接口🤔,那么我们怎么用接口呢?
🍑哈哈,很简单😉,我们再用一个普通类实现这个接口不就行了吗😂,不同的是抽象类是被子类来继承而实现的,而接口与类之间则是用关键字implements来实现。
📝就像普通类实现实现抽象类一样,一个类实现某个接口则必须实现该接口中的抽象方法,否则该类必须被定义为抽象类🤔。
通过接口实现多态
🍑铁汁们!刚才我们是用抽象类来实现多态,那么现在我们可以尝试用接口来实现多态,嘻嘻😎
接口可以看成是一种特殊的类,只能用 interface 关键字修饰 interface IShape { int a = 10; 接口当中的成员变量默认都是public static final int b = 23; void draw(); 接口当中的成员方法一般只能是抽象方法,默认是public abstract(JDK1.8以前) default void show() { System.out.println("接口中的其他方法");//接口中的其他方法也可以实现,但要用default修饰 } public static void test() { System.out.println("这是接口当中的一个静态的方法"); } } // 一个普通的类要想实现接口,可以用implement, //因为接口也是抽象方法的,所以实现接口的这个类也要重写抽象方法 class Cycle implements IShape { @Override public void draw() { System.out.println("画一个圆圈"); } } class Square implements IShape { @Override public void draw() { System.out.println("画一个正方形"); } } class Flower implements IShape { @Override public void draw() { System.out.println("画一朵花"); } } public class Test4 { public static void main(String[] args) { // IShape iShape = new IShape(); 接口也不能直接实例化 Cycle cycle = new Cycle(); Square square = new Square(); Flower flower = new Flower(); // 这里的IShape接口就相当与抽象类中父类,接口类型也是一种引用类型 IShape[] iShapes = {cycle, square, flower}; // 这个过程其实就发生了向上转型 for (IShape iShape : iShapes) { // 增强型的for—each循环,也可以写成普通的for循环形式 iShape.draw(); // 通过重写实现了多态 } } } 引用变量cycle和square都赋值给了Shape类型的引用变量shape, 但当执行shape.draw()时,java虚拟机到底要调用谁重写的的draw方法, 就看此时接口引用的是那个对象的,是shape的、还是cycle的
😎看一下运行结果😎
看完代码你可能有点晕😫,但没关系。一般接口咱也不这么用,直接使用抽象类不就好了😉(我只是演示一下用接口也能实现多态😂)
🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑
📝下面我们来总结一下Java中接口的几个主要特点
- 🌰接口中可以包含变量和方法,变量被隐式指定为 public static final,方法被隐式指定为 public abstract(JDK 1.8 d一个类可以同时实现多个接口,一个类实现某个接口则必须实现该接口中的抽象方法,否则该类必须被定义为抽象类
- 🌰接口支持多继承,即一个接口可以继承(extends)多个接口,间接解决了 Java 中类不能多继承的问题。
🍑那么接口一般用在什么地方呢?
- 一般情况下,实现类和它的抽象类之前具有 "is-a" 的关系,但是如果我们想达到同样的目的,但是又不存在这种关系时,使用接口。
- 由于 Java 中单继承的特性,导致一个类只能继承一个类,但是可以实现一个或多个接口,此时可以使用接口。
🌰下面就让我们来看看接口的正确用法:帮助java实现“ 多继承 ”😎
由于 Java 中单继承的特性,导致一个类只能继承一个类,但是可以实现一个或多个接口,此时可以使用接口。 class Animal { String name; // 不能使用private,后面的子类也要用 public Animal(String name) { // 父类的自定义的构造方法 this.name = name; } } interface IFlying { // 自定义多种接口 void fly(); } interface IRunning { void run(); } interface ISwimming { void swimming(); } // 小鸭子,不仅会跑,还会游泳、飞行 一个类继承父类,并实现多个接口,间接的解决java中不能多继承的问题 class Duck extends Animal implements IRunning, ISwimming, IFlying { public Duck(String name) { // 子类构造方法 super(name); // 必须在子类构造方法的第一行 // 在给实现子类的构造方法前,先要用super()调用实现父类的构造方法,比较先有父后有子呀! // 因为父类自己定义了构造方法,编译器不会自动给给子类构造方法中添加super();来实现父类的构造方法,需要我们自己实现 } // 对接口中的抽象方法进行重写 @Override public void fly() { System.out.println(this.name + "正在用翅膀飞"); } @Override public void run() { System.out.println(this.name + "正在用两条腿跑"); } @Override public void swimming() { System.out.println(this.name + "正在漂在水上"); } } public class 接口的使用 { // 不用学我用中文名作为类名,我只是为演示方便 public static void main(String[] args) { Duck duck = new Duck("第一个小鸭子"); // 实例化鸭子对象 duck.fly(); // 通过引用 变量名.方法名 输出重写后的方法 duck.run(); duck.swimming(); } } 有人可能会说干嘛用接口,我直接在父类Animal中实现fly、run、swimming这些属性, 然后不同的动物子类再继承父类这些方法不行吗? 但问题是,鸭子会fly、swimming,那猫会飞和游泳吗?你再写个其他动物的子类是不是就不行了 而用接口呢?我们只是把这种飞、游泳的行为给抽象出来了, 只要一个子类有这种行为,他就可以实现相对应的接口,接口是更加灵活的
📝上面的代码展示了 Java 面向对象编程中最常见的用法: 一个类继承一个父类, 同时实现多个接口。
📝继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性 ,能实现接口的类和该接口并不一定有is_a的关系,只要该类有这个接口的特性就行
猫是一种动物, 具有会跑的特性.
青蛙也是一种动物, 既能跑, 也能游泳
鸭子也是一种动物, 既能跑, 也能游, 还能飞
🍑这样设计有什么好处呢? 时刻牢记多态的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型,只要这个类有有这个特性就好。
举个栗子🌰
class Robot implements IRunning { private String name; public Robot(String name) { this.name = name; } // 对run方法进行重写 @Override public void run() { System.out.println("机器人" + this.name + "正在跑"); } } public class Test4 { public static void main(String[] args) { Robot robot1 = new Robot("图图"); robot1.run(); } } // 执行结果 机器人图图正在跑
😎只要能跑就行,管他是机器人还是动物呢😂,接口是不是很灵活呀!
同时在实际的开发过程中,一般来说,一个类是一个Java文件,一个接口也是一个Java文件。大家也要在平时就养成这个好习惯呀!
哈哈,不知道现在你对抽象类和接口的认识是不是又上升了一个高度呢?嘻嘻,我们下篇博客再见了,下篇让我们瞅瞅Java中常用的接口有哪些😉
每天进步一点点,铁汁们,一起加油😎😎😎
-
java 中接口和抽象类的区别与对比
2020-08-29 13:34:52主要介绍了java 中接口和抽象类的区别与对比的相关资料,这里详细说明他们之家的区别,需要的朋友可以参考下 -
Java中抽象类和接口的区别及应用场景
2022-03-17 19:25:18下面会简单介绍抽象类和接口的定义,并根据它们的属性,了解他们的区别,同时也会引导出他们的适用场景。如有缺陷请斧正。 抽象类 定义:用abstract关键字修饰的类就是抽象类。例:abstract class A{} 注意: ... -
Java中抽象类和接口区别详细总结,附JDK1.8的新特性
2019-08-24 21:05:28抽象类:使用abstract修饰,使用时,子类用extends继承! 接口:使用interface修饰,使用时,具体实现类用implements实现! 按照类中所有元素,层次的区分两者: ...(1)抽象类可以有普通成员变量,接口不... -
Java接口和抽象类的区别深入剖析
2020-09-04 09:16:49主要介绍了Java接口和抽象类的区别,对于Java的初学者来说是需要准确掌握的概念! -
Java 抽象类与接口区别是什么?
2021-02-27 11:40:04Java 抽象类与接口区别是什么?1、抽象类可以提供某些方法的部分实现,而接口不可以;2、抽象类是单个继承机制,其子类不一定要实现父类中的所有没实现的方法,而接口一个类可以有多个接口,并且方法都要实现。理解... -
Java中的类、抽象类和接口的区别和联系
2012-04-07 19:03:14Java中的类、抽象类和接口的区别和联系 -
Java抽象类和接口的区别
2020-02-09 16:56:31抽象类:如果一个类含有抽象方法(抽象方法是一种特殊的方法,它只有声明,而没有具体的实现),则称这个类为抽象类,...包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样... -
java 抽象类与接口的区别介绍
2020-09-01 10:41:52主要介绍了java 抽象类与接口的区别介绍的相关资料,需要的朋友可以参考下 -
Java中抽象类和接口的区别与作用详解
2010-03-23 10:40:27结论:abstract class和Interface是JAVA语言中的两种定义抽象类的方式。Interface将abstract的概念作了更进一步的发挥。你可以想像Interface是“纯粹”的 abstract class,只可以包含抽象方法,也包括一些常量的定义... -
简述Java中抽象类和接口,及其两者区别
2018-04-19 13:00:48在说区别之前,先简要说一下什么是抽象类和接口 1.抽象类 用abstract修饰的类叫做抽象类。 在讲抽象类之前有必要强调一下abstract修饰符: 1.abstract修饰的类为抽象类,此类不能有对象,... -
java中接口和抽象类的区别
2018-09-21 23:18:35接口和抽象类的区别? 接口(interface)和抽象类(abstract class)是支持抽象类定义的两种机制。 接口是公开的,不能有私有的方法或变量,接口中的所有方法都没有方法体,通过关键字interface实现。 抽象类是可以有... -
Java中普通类、抽象类、接口三者的区别和联系
2021-02-28 22:43:071. 抽象类 1.1 抽象方法理解 定义: 只有方法的申明,没有具体的实现即方法体。 例如: abstract void test(); 注意: 抽象方法必须使用abstract修饰,否则编译时会...1.3 抽象类和普通类的区别 1.抽象方法必须被访 -
java中接口和抽象类的区别(保证你一看就懂)
2021-02-25 10:48:393、接口中的变量必须给出初始值,抽象类可以不给; 4、一个类只能继承一个抽象类,但可以实现多个接口; 5、抽象类中可以写非抽象的方法,从而避免在子类中重复书写它们,这样可以提高代码的复用性,这是抽象类的... -
Java中抽象类与接口有什么区别
2019-06-13 20:55:16abstract class和interface是Java中对于抽象类定义两种机制,正是由于这两种机制的存在,才赋予Java强大的面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有相当大的相似性,设置可以互相... -
Java 抽象类和接口
2021-11-14 16:09:56接口的特征三、抽象类和接口的区别 一、抽象类 1.抽象类 1.1抽象类的定义 在Java面向对象当中,所有的对象都是用过类进行描绘的,但是并不是所有的类都是用来描绘对象的,如果一个类没有包含足够多的信息来描述一个... -
Java接口和抽象类的区别
2020-12-06 15:13:33接口中可以有变量和方法,但是变量会被隐式的指定为public static final变量,而方法会被指定为public abstract【所有方法在接口中不能有实现,也说明接口中都是抽象方法】,(Java 8 开始接⼝⽅法可以有默认实现)... -
Java中抽象类与接口区别
2017-12-20 09:18:19抽象类:抽象类是无法实例化的特殊类。所以问题是为什么我们需要一个不能被实例化的类,抽象类只能是子类(继承自)。换句话说,它只允许其他类继承它,但不能实例化。优点是它为所有子类执行特定的层次结构。简而言之... -
java中抽象类和接口的异同点
2019-09-25 23:05:57抽象类: 关键字abstract 可以修饰类,也可以修饰方法 修饰类的话,可以创建构造方法,但是不可以被实例化,创建构造方法的目的是为了子类的调用 有抽象方法的类一定是抽象类,抽象类可以没有抽象方法,抽象类... -
一、Java中接口和抽象类的区别?
2019-10-24 15:41:23Java中接口和抽象类的区别 -
举例说明java中抽象类和接口的区别
2018-04-13 11:42:32最近才了解到:如果一个类继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法进行实现,否则该类需要被声明为抽象类。而在接口中有几点需要注意:1.接口中的所有方法都是抽象方法(和修饰词abstract没有一点... -
Java中关于抽象类和接口的说法,多选题
2021-03-10 03:05:07展开全部答案:ABCFJava 抽象类在面向对象的概念中,所有的对象都是通过类来32313133353236313431303231363533e58685e5aeb931333431343036描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有... -
Java中接口和抽象类的区别与相同之处
2021-03-16 22:45:17Java抽象类和Java接口一样,都用来声明一个新的类型。并且作为一个类型的等级结构的起点。(2).格式:public abstract class abstractDemo{/**属性*/private String name;/**方法*/public abstract void f... -
Java中抽象类和接口中有构造方法吗?
2021-03-08 05:52:39以举例的方式说到如何区分抽象类和接口,这里我们从Java语法谈起,使我们更加了解这两者的内在区别。它们的语法区别:1)接口不能有构造方法,抽象类可以有。2)接口不能有方法体,抽象类可以有。3)接口不能有静态方法... -
java抽象类和接口有什么意义
2021-02-04 16:53:06为什么接口和抽象类不能实例化,为什么接口可以多个实现而抽象类只能单继承,特别是java8之后,抽象类和接口里面都可以写代码后,就更加分不清了,今天重新整理一下。 什么是抽象类(abstract class) 使用abstract... -
Java中抽象类实现接口
2021-05-06 14:22:31Java中的抽象类主要是作为一个公共父类的作用,它可以抽象出用来描述一种类型应该具备的基本特征与功能,具体行为则由子类通过方法重写来完成。 抽象类具有的性质 类定义前需要加上abstract关键字 抽象类中可以没有...