抽象类:
没有实际工作的方法可以被设计为抽象方法(abstract method),包含抽象方法的类就称为抽象类(abstract class)包含抽象方法的类必须加上abstract关键字来表示这是一个抽象类。
注意!!!
(1)抽象类不能直接实例化
(2)抽象方法不能是private的
(3)抽象类中可以包含其他的非抽象方法,也可以包含字段,这个非抽象方法和普通方法的规则都是一样的,也可以被重写,也可以被子类直接调用。
为什么要使用抽象类?
抽象类存在的最大意义是为了继承。抽象类本身不能被实例化,要想使用,只能创建该抽象类的子类,然后让子类重写抽象类中的方法。因为有时候实际工作不应该由父类完成而应该由子类完成,如果不小心误用成父类了,使用普通编译器是不会报错的,但是父类抽象类就会在实例化的时候提示错误,让我们尽早发现错误。
接口:
接口是抽象类的更进一步,抽象类中还可以包括非抽象方法和字段,而接口中的包含的方法都是抽象方法,字段也只能是静态常量(final static)
接口的语法规则:
class shape {
public void draw(){
//啥都不用干
}
}
class Cycle extends shape{
@Override
public void draw(){
System.out.println("⭕️");
}
}
public class Test {
public static void main(String[] args){
shape Shape=new Cycle();
drawshape(Shape);
}
public static void drawshape(shape Shape){
Shape.draw();
}
}
上面的打印圆形的代码中父类shape没有包含别的非抽象方法,可以设计成一个接口:
1、使用interface定义一个接口
2、接口中的方法一定是抽象方法、public,因此可以省略abstract、public
3、Cycle使用implements继承接口,此时表达的含义不再是“继承”(extends:已有部分功能,进一步扩充),而是“实现”(implements:没有功能,需要从头构造出来)
4、在调用的时候同样可以创建一个接口的引用,对应到一个子类的实例
5、接口不能单独被实例化
6、创建接口的时候,接口命名一般要以大写字母I
开头、使用形容词词性的单词
interface Ishape {
void draw();
}
class Cycle implements Ishape{
@Override
public void draw(){
System.out.println("⭕️");
}
}
public class Test {
public static void main(String[] args){
Ishape Shape=new Cycle();
Shape.draw();
}
}
如何实现多个接口?
有时候我们需要让一个类同时继承自多个父类,在其他有些编程语言中可以使用多继承方法,但是Java只支持单继承:一个类只能extends一个父类,但是可以同时实现多个接口,也能达到多继承类似的效果(IDEA中使用ctrl+i快速实现接口)
注意:
继承表达的含义是:is-a
接口表达的含义是:具有xxx特性
多态可以让类的使用者不关注类的类型,接口可以让类的使用者不关注类的类型,只关注某个类是否具备某种特性。
如何使用接口?
例:给对象数组排序
package java_20200520;
//排名标准:
//1、先看分数score
//2、再看颜值faceValue
public class Student implements Comparable<Student> {
private String name;
private int score;
private int faceValue;
public Student(String name, int score, int faceValue) {
this.name = name;
this.score = score;
this.faceValue = faceValue;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
", faceValue=" + faceValue +
'}';
}
@Override
public int compareTo(Student o) {
//比较this和other
//array[cur-1]是this,array[cur]是other
//[cur-1]是前一个元素,[cur]是后一个元素
//compareTo结果<0,说明当前的两个元素的位置是符合要求的
//compareTo结果>0,说明当前位置不符合要求,应该要交换。
//如果this在other前面,就应该返回<0
//如果this在other后面,就应该返回>0
//如果this和other并列,就应该返回0
if(this.score>o.score){
return -1;//this在前
}if(this.score<o.score){
return 1;//other在前
}if(this.faceValue>o.faceValue){
return -1;
}if(this.faceValue<o.faceValue){
return 1;
}//二者都一样就不分先后。
return 0;
}
}
测试部分:
package java_20200520;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
Student[] students = {
new Student("彭于晏", 96, 100),
new Student("周杰伦", 96, 97),
new Student("林俊杰", 97, 90),
new Student("吴亦凡", 92, 98)
};
//Arrays.sort(students);//排序
sort(students);
System.out.println(Arrays.toString(students));
}
public static void sort(Comparable[] array){
for(int bound=0;bound<array.length;bound++){
for(int cur=array.length-1;cur>bound;cur--){
if(array[cur-1].compareTo(array[cur])>0){
Comparable tmp=array[cur-1];
array[cur-1]=array[cur];
array[cur]=tmp;
}
}
}
}
}