世界地球日,奏响低碳生活进行曲,以蓝天为乐谱,以绿树为音符,以碧水为琴弦弹奏出环保最强音,为地球母亲祈祷平安吃五谷杂粮,穿天然布衣,住节能住宅,行无车之旅,用厉行节俭。让我们怀着敬畏感恩之心,向地球母亲贺寿。
科普
知识
前言
在前面两周,我们分别学习了抽象类和接口,在上一周的学习中,不知道大家有没有注意到这样一句话“但当一个抽象类除了抽象方法外什么都没有的时候,用接口则更为合适”,即从这句话中,我们可以看出,其实接口也是一种特殊的抽象类。那么本周我们就来看看两者又有哪些联系与区别。
一、抽象类
在 Java 中,被关键字 abstract 修饰的类称为抽象类;被 abstract 修饰的方法称为抽象方法,抽象方法只有方法声明没有方法体。
抽象类有以下几个特点:
抽象类不能被实例化,只能被继承;
包含抽象方法的类一定是抽象类,但抽象类不一定包含抽象方法(抽象类可以包含普通方法);
抽象方法的权限修饰符只能为 public、protected 或 default,默认情况下为 public;
一个类继承于一个抽象类,则子类必须实现抽象类的抽象方法,如果子类没有实现父类的抽象方法,那子类必须定义为抽象类;
抽象类可以包含属性、方法、构造方法,但构造方法不能用来实例化对象,只能被子类调用。
二、接口
接口可以看成是一种特殊的类,只能用 interface 关键字修饰。
Java 中的接口具有以下几个特点:
接口中可以包含变量和方法,变量被隐式指定为 public static final,方法被隐式指定为 public abstract(JDK 1.8 之前)。
接口支持多继承,即一个接口可以继承(extends)多个接口,间接解决了 Java 中类不能多继承的问题。
一个类可以同时实现多个接口,一个类实现某个接口则必须实现该接口中的抽象方法,否则该类必须被定义为抽象类。
三、抽象类和接口的联系与区别
联系:
接口和抽象类很像,它们都具有如下特征:
接口和抽象类都不能被实例化,主要用于被其他类实现和继承。
接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
区别:
接口作为系统与外界交互的窗口,接口体现的是一种规范。对于接口的实现者而言,接口规定了实现者必须向外提供哪些服务(以方法的形式来提供);对于接口的调用者而言,接口规定了调用者可以调用哪些服务,以及如何调用这些服务(就是如何来调用方法)。当在一个程序中使用接口时,接口是多个模块间的耦合标准;当在多个应用程序之间使用接口时,接口是多个程序之间的通信标准。
从某种程度上来看,接口类似于整个系统的“总纲”,它制定了系统各模块应该遵循的标准,因此一个系统中的接口不应该经常改变。一旦接口被改变,对整个系统甚至其他系统的影响将是辐射式的,会导致系统中大部分类都需要改写。
一个类最多只能有一个直接父类,包括抽象类,但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足。
抽象类则不一样,抽象类作为系统中多个子类的共同父类,它所体现的是一种模板式设计。抽象类作为多个子类的抽象父类,可以被当成系统实现过程中的中间产品,这个中间产品已经实现了系统的部分功能(那些已经提供实现的方法),但这个产品依然不能当成最终产品,必须有更进一步的完善,这种完善可能有几种不同方式。
四、接口和抽象类在用法上的区别
除了上述提到的区别之外,接口和抽象类在用法上也存在差别,如下表所示:
五、抽象类和接口的应用场景
抽象类的应用场景:
父类只知道其子类应该包含怎样的方法,不能准确知道这些子类如何实现这些方法的情况下,使用抽象类。
从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性。
接口的应用场景:
一般情况下,实现类和它的抽象类之前具有 "is-a" 的关系,但是如果我们想达到同样的目的,但是又不存在这种关系时,使用接口。
由于 Java 中单继承的特性,导致一个类只能继承一个类,如果想实现多重继承,那么必须使用接口。
小编有话说
小编最近有点忙,就先奉上上周习题的参考答案吧。大家加油哟!
考虑到图有点小,就把源码附上吧~
1.Student抽象类
package code.tisheng7;
public abstract class Student {
public int stuID;
public String name;
public float score;
public double weight;
public Student(int stuID, String name,float score) {//三个参数的构造方法
this.stuID = stuID;
this.name = name;
this.score = score;
}
public Student(int stuID, String name,float score,double weight) {//四个参数的构造方法
this.stuID = stuID;
this.name = name;
this.score = score;
this.weight = weight;
}
public abstract double getscore(); // 定义抽象方法,计算分数
}
2.Pupil类
package code.tisheng7;
public class Pupil extends Student {
public Pupil(int stuID, String name,float score) {
super(stuID,name,score);
}
public String getname(){
return ("学号:"+stuID+","+name);
}
// 重写父类中的抽象方法,获得成绩
@Override
public double getscore() {
return score;
}
}
3.Undergraduate类
package code.tisheng7;
public class Undergraduate extends Student {
public Undergraduate(int stuID, String name,float score,double weight) {
super(stuID,name,score,weight);
}
public String getname(){
return ("学号:"+stuID+","+name);
}
// 重写父类中的抽象方法,实现大学生的权重成绩
@Override
public double getscore() {
return score*weight;
}
}
4.Test_student类
package code.tisheng7;
public class Test_student {
public static void main(String[] args) {
Pupil pupil = new Pupil(123, "李雷居士",89); // 创建pupil对象
System.out.println(pupil.getname()+"的成绩为:"+pupil.getscore());
// 创建圆Undergraduate对象
Undergraduate undergraduate = new Undergraduate( 456,"韩梅梅居士",98,0.6);
System.out.println(undergraduate.getname()+"加权成绩为:"+undergraduate.getscore());
}
}
编辑:玥怡居士|审核:世外居士
精彩推荐
-扫码关注我们-
IT进阶之旅
点击"在看"了解更多精彩内容