抽象类和接口
一.抽象类和抽象方法
1.概述
在Java中,—个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
2.特点
抽象类
①抽象类被abstract修饰
②抽象类无法实例化对象
③抽象类存在的意义就是为了让子类继承
④抽象类和普通类的区别:抽象类里面有抽象方法,普通类里面不能有抽象方法,抽象类里面可以有普通方法
抽象方法
①抽象方法用abstract修饰,抽象方法没有方法体
②一个类中有抽象方法,则这个类必须定义为抽象类
③抽象方法存在的意义就是为了让子类重写,权限修饰符不能是private final
④子类必须重写抽象类的所有抽象方法,除非子类也是抽象类
以下通过代码演示抽象类、子类继承抽象类以及抽象类不能实例化对象
public abstract class Shape {
private String shapeName;
private final int AREA=10;
public Shape(){}
public Shape(String shapeName){
this.shapeName=shapeName;
}
public String getShapeName() {
return shapeName;
}
public void setShapeName(String shapeName) {
this.shapeName = shapeName;
}
public int getAREA() {
return AREA;
}
//抽象方法存在的意义:为了让子类重写
public abstract void draw();
public void test(){
System.out.println("这个是shape中的test方法,主要是为了测试抽象类中可以有成员方法");
}
}
//如果子类不重写父类的抽象方法,除非子类是抽象类
public class Flower extends Shape{
public Flower(String shapeName) {
super(shapeName);
}
@Override
public void draw() {
System.out.println(getShapeName());
}
}
public class Demo01 {
public static void main(String[] args) {
//Shape s=new Shape() 抽象类不能实例化对象
Shape s1=new Flower("花");
System.out.println(s1.getShapeName());
System.out.println(s1.getAREA());
s1.draw();
}
}
二.接口
1.定义
接口是 Java 中一种抽象类型,它只包含抽象方法(Java 8 开始可以包含 default 方法和静态方法)和常量。接口的定义使用 interface 关键字,另外,接口定义的所有方法默认都是public abstract,所以这两个修饰符不需要显示的定义出来(写或不写效果都一样)。当一个具体的class去实现一个interface时,需要使用implements关键字。
2.语法
①定义接口
修饰符 interface 接口名{
//成员常量:默认用public static final修饰
//抽象方法:默认用public abstract 修饰
//默认方法:public default void defaultMethod(){}
也可以省略public
//静态方法:public static 返回值类型 方法名{}
}
②使用接口
修饰符 class 类名 implements 接口{
//重写接口中所有的抽象方法,除非子类是抽象类
}
以下通过代码演示接口及其它的实现类
//接口:一个抽象类中没有成员变量,并且所有的方法都是抽象方法
//修饰符 interface 接口名{
// 成员常量 抽象方法 默认方法 静态方法
// }
//1.接口中的所有抽象方法默认用:public abstract 修饰
//2.接口中的所有成员变量均是成员常量:public static final修饰
//3.接口中没有变量 接口中不能有普通方法 接口中不能有构造方法
public interface IShape {
double PI=3.14;
void draw();
void test();
}
//实现类:
//修饰符 class 类名 implements 接口名{
// 重写接口中所有的抽象方法 除非子类是抽象类
// }
public class Circle implements IShape{
@Override
public void draw() {
System.out.println("画圆");
}
@Override
public void test() {
System.out.println("这个是Circle的test方法");
}
}
public class Demo01 {
public static void main(String[] args) {
//面向抽象设计:
//接口类型 对象名=new 实现类();
IShape s1=new Circle();
s1.test();
s1.draw();
//s1.PI=3.1415;接口中的常量不能被重新赋值
System.out.println(s1.PI);
}
}
3.特点
①接口不能实例化(创建对象)
②接口中不能有构造方法,不能有静态代码块,接口里面抽象方法默认用public abstract修饰
③接口的实现类必须实现接口中的所有抽象方法
4.接口和类的关系
1.类与类之间是单继承:一个子类只能有一个父类,一个父类可以有多个子类
2.类和接口是多实现:一个类可以实现多个接口,一个接口可以被多个类实现
3.接口和接口关系:接口可以继承一个或多个
4.类可以继承另一个类(单继承),也可以实现多个接口
// 先继承后实现
public class 类名 extends 父类 implements 接口名1,接口名2{}
三.接口的继承
1.一个interface可以继承自另一个interface。interface继承interface同样也使用extends关键字,它相当于扩展了接口的方法。
以下通过代码演示类可以继承类的同时实现多个接口,以及接口之间的多继承关系
public interface IFlying {
void fly();
}
interface IRunning {
void run();
}
interface ISwimming {
void swim();}
//接口之间可以多继承
interface IAAA extends IRunning,ISwimming{
}
父类Animal
public class Animal {
protected String nameString;
public Animal(String nameString) {
this.nameString = nameString;
}
}
子类Dog
public class Dog extends Animal implements IRunning{
public Dog(String nameString) {
super(nameString);
}
@Override
public void run() {
System.out.println("小狗"+nameString+"正在跑");
}
}
子类Frog
public class Frog extends Animal implements IAAA{
public Frog(String nameString) {
super(nameString);
}
@Override
public void run() {
System.out.println("青蛙"+nameString+"正在跑");
}
@Override
public void swim() {
System.out.println("青蛙"+nameString+"正在游泳");
}
}
子类Duck
public class Duck extends Animal implements IAAA,IFlying{
public Duck(String nameString) {
super(nameString);
}
@Override
public void fly() {
System.out.println("鸭子"+nameString+"正在飞");
}
@Override
public void run() {
System.out.println("鸭子"+nameString+"正在跑");
}
@Override
public void swim() {
System.out.println("鸭子"+nameString+"正在游泳");
}
}
测试类
public class Demo02 {
public static void main(String[] args) {
//向上转型 对外声明IRunning
//强调跑的本领
IRunning r1=new Dog("旺财");
IRunning r2=new Frog("青蛙王子");
IRunning r3=new Duck("奋斗鸭");
r1.run();
r2.run();
r3.run();
//强调飞的本领
IFlying f1=new Duck("鸭子");
f1.fly();
//如果想要用当前对象独有的方法,则需要向下转型
if(f1 instanceof Duck){
Duck d1=(Duck) f1;
d1.swim();
}
}
}
四.default方法
1.在JDK 1.8及其更高版本中,接口中可以定义default方法。
2.接口中的 default 方法提供了默认实现,实现该接口的类可以选择重写该方法,也可以不重写,直接使用接口提供的默认实现。
五.抽象类和接口的区别
六.Comparable接口
Comparable接口用于进行对象之间的比较,主要用于排序方法。
代码示例
public class Demo03 {
public static void main(String[] args) {
Book b1=new Book("java",5,20);
Book b2=new Book("javaweb",20,35);
Book b3=new Book("html",2,66);
Book b4=new Book("C",25,88);
Book b5=new Book("php",52,99);
Book[] books={b1,b2,b3,b4,b5};
//如果是自定义的数组的数据类型,需要实现比较接口才能进行排序
//对于自定义的数据类型,java编译器不知道如何比较两个对象的大小,无法自动确定排序的标准
//为了解决这个问题,java提供了比较接口Comparable
Arrays.sort(books);//一旦类实现了Comparable接口,就可以使用Arrays.sort对对象数组进行排序
//创建了一个Book对象数组,并使用 Arrays.sort(books) 对其进行排序。
//因为Book类实现了Comparable<Book>接口,Arrays.sort会调用Book类的compareTo方法来确定对象的顺序。
for (Book b:books){
System.out.println(b);
}
}
}
public class Book implements Comparable<Book> {
private String bookName;
private int pageSize;
private double price;
// 构造方法
public Book(String bookName, int pageSize, double price) {
this.bookName = bookName;
this.pageSize = pageSize;
this.price = price;
}
//结果为负数的时候会进行两两交换
// 实现Comparable接口的compareTo()方法
// 比较当前对象this与另外一个Book对象的大小
// this > o 返回 大于零的值
// this == o 返回 零 返回0 1升序
// this < o 返回小于零的值 返回-1 降序
@Override
//比较两个Book对象的大小
public int compareTo(Book o) {
if (this.pageSize > o.pageSize) {
return 1;
} else if (this.pageSize == o.pageSize) {
if (this.price > o.price) {
return 1;
} else if (this.price == o.price) {
return 0;
} else {
return -1;
}
} else {
return -1;
}
}
@Override
public String toString() {
return "Book[" +
"bookName='" + bookName + '\'' +
", pageSize=" + pageSize +
", price=" + price +
']';
}
}
运行结果
标签:void,接口,Book,抽象类,方法,public From: https://blog.csdn.net/weixin_64111255/article/details/145228774