目录
抽象类
接口
接口用static和default的方法
Comparable
Comparator
Comparable和Comrarator的区别
接口实现冒泡排序
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类
abstract class 类名{//抽象类
abstract void shout();//抽象方法
}
1. 抽象类不能直接实例化对象
// 抽象类:被abstract修饰的类
public abstract class Shape {
// 抽象方法:被abstract修饰的方法,没有方法体
abstract public void draw();
abstract void calcArea();
// 抽象类也是类,也可以增加普通方法和属性
public double getArea(){
return area;
}
protected double area; // 面积
}
2. 抽象方法不能是 private 的
private 的 abstract class Shape {
abstract private void draw();
}
// 编译出错
Error:(4, 27) java: 非法的修饰符组合: abstract和private
public abstract class Shape {
abstract final void methodA();
abstract public static void methodB();
}
4. 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修 饰
// 矩形类
public class Rect extends Shape {
private double length;
private double width;
Rect(double length, double width){
this.length = length;
this.width = width;
}
public void draw(){
System.out.println("矩形: length= "+length+" width= " + width);
}
public void calcArea(){
area = length * width;
}
}
// 圆类:
public class Circle extends Shape{
private double r;
final private static double PI = 3.14;
public Circle(double r){
this.r = r;
}
public void draw(){
System.out.println("圆:r = "+r);
}
public void calcArea(){
area = PI * r * r;
}
}
// 三角形类:
public abstract class Triangle extends Shape {
private double a;
private double b;
private double c;
@Override
public void draw() {
System.out.println("三角形:a = "+a + " b = "+b+" c = "+c);
}
// 三角形:直角三角形、等腰三角形等,还可以继续细化
//@Override
//double calcArea(); // 编译失败:要么实现该抽象方法,要么将三角形设计为抽象类
}
5. 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
6. 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量
注意:抽象类也是类,内部可以包含普通方法和属性,甚至构造方法
多个类的公共规范,可以说是属于一种标准,是一种引用数据类型
1. 接口类型是一种引用类型,但是不能直接new接口的对象
public class TestUSB {
public static void main(String[] args) {
USB usb = new USB();
}
}
// Error:(10, 19) java: day20210915.USB是抽象的; 无法实例化
public interface USB {
// Error:(4, 18) java: 此处不允许使用修饰符private
private void openDevice();
void closeDevice();
}
3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
public interface USB {
void openDevice();
// 编译失败:因为接口中的方式默认为抽象方法
// Error:(5, 23) java: 接口抽象方法不能带有主体
void closeDevice(){
System.out.println("关闭USB设备");
}
}
4. 重写接口中方法时,不能使用默认的访问权限
public interface USB {
void openDevice(); // 默认是public的
void closeDevice(); // 默认是public的
}
public class Mouse implements USB {
@Override
void openDevice() {
System.out.println("打开鼠标");
}
// ...
}
// 编译报错,重写USB中openDevice方法时,不能使用默认修饰符
// 正在尝试分配更低的访问权限; 以前为public
5. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量
public interface USB {
double brand = 3.0; // 默认被:final public static修饰
void openDevice();
void closeDevice();
}
public class TestUSB {
public static void main(String[] args) {
System.out.println(USB.brand); // 可以直接通过接口名访问,说明是静态的
// 编译报错:Error:(12, 12) java: 无法为最终变量brand分配值
USB.brand = 2.0; // 说明brand具有final属性
}
}
6. 接口中不能有静态代码块和构造方法
public interface USB {
// 编译失败
public USB(){
}
{} // 编译失败
void openDevice();
void closeDevice();
}
static不能重写第一个必须重写,第三个default可重写也可以不重写
Comparable是接口,表示当前的类是可以进行比较的
class Student implements Comparable
<>括号里写的谁就比较谁
compareTo是Comparable这个接口的方法
Comparable的运用:如图
例子:
class Student implements Comparable {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student o) {
return this.age - o.age;
//return o.age - this.age;//从大到小
}
/* if (this.age > o.age) {
return 1;
} else if (this.age == o.age) {
return 0;
} else {
return -1;
}
}*/
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) {
Student student1 = new Student("1", 10);
Student student2 = new Student("11", 11);
System.out.println(student1.compareTo(student2));
}
}
Comparator灵活一点,可以根据你想要的属性来排序,下面有例子可以看看
例子:
class Student {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
class AgeComparator implements Comparator {//AgeComparator如果想根据姓名比较,直接换成NameComparator
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
class NameComparator implements Comparator {
@Override
public int compare(Student o1, Student o2) {
//String 自己重写的 compareTo 方法
return o1.name.compareTo(o2.name);
}
}
public class Test {
public static void main(String[] args) {
Student student1 = new Student("1", 10);
Student student2 = new Student("11", 11);
AgeComparator ageComparator = new AgeComparator();
System.out.println(ageComparator.compare(student1, student2));
NameComparator nameComparator = new NameComparator();
System.out.println(nameComparator.compare(student1, student2));
}
}
Comrarator比较灵活,Comparable根据默认的属性来进行排序,不需要那么麻烦点
package demo1;
import java.util.Arrays;
import java.util.Comparator;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 楠
* Date: 2024-02-03
* Time: 15:17
*/
class Student implements Comparable {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
@Override
public String toString() {
return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
class AgeComparator implements Comparator {//AgeComparator如果想根据姓名比较,直接换成NameComparator
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;//从大到小反过来
}
}
class NameComparator implements Comparator {
@Override
public int compare(Student o1, Student o2) {
//String 自己重写的 compareTo 方法
return o1.name.compareTo(o2.name);
}
}
public class Test {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("qwe", 18);
students[1] = new Student("asd", 14);
students[2] = new Student("zxc", 12);
AgeComparator ageComparator = new AgeComparator();
Arrays.sort(students);//这样就是默认的Comparable<>进行比较
//Arrays.sort(students, ageComparator);//根据年龄排序,只能要改掉第二个参数以及源代码就可以按照你想要的格式排序
System.out.println(Arrays.toString(students));
}
}
注意事项: 对于 sort 方法来说, 需要传入的数组的每个对象都是 "可比较" 的, 需要具备 compareTo 这样的能力,通过重写 compareTo 方法的方式, 就可以定义比较规则
前提是要实现接口comparable
为了进一步加深对接口的理解, 我们可以尝试自己实现一个 sort 方法来完成刚才的排序过程(使用冒泡排序)