一、抽象类
1、包含抽象方法的类,叫做抽象类
2、抽象方法。一个没有具体实现的方法,被abstract修饰
eg:
abstract class Shape {
public int a;
public void func(){
System.out.println("测试");
}
public abstract void draw();
}
·在draw方法前加上abstract,表示这是一个抽象方法,同时抽象方法没有方法体(没有{},不能执行具体代码)
·对于包含抽象方法的类,必须加上abstract关键字声明这是一个抽象类
3、不可实例化
在main函数中new一个Shape。编译结果如下:
public static void main(String[] args) {
Shape shape = new Shape() {
}
}
4、因不能实例化,所以只能被继承
5、抽象类中,可以包含和普通类一样的成员和方法
从第一点的代码中我们可以看出,抽象类中可以包含和普通类一样的成员变量和方法。规则和普通类类似,可以被重写,也可以被子类直接使用。
6、普通类继承抽象类,普通类中需要重写抽象类中的所有抽象方法
class Rect extends Shape{
@Override
public void draw(){
System.out.println("♦");
super.func();
}
}
此时我们定义一个类Rect(♦),类Rect通过extengs继承自抽象类Shape。
此时我们就需要重写抽象类当中的draw方法。
7、最大的作用→被继承
8、一个抽象类A,如果继承了一个抽象类B,那么这个抽象类A可以不实现父类的抽象方法
abstract class A extends Shape{
public abstract void funcA();
}
此时我们定义一个新的抽象类A,类A继承自抽象类Shape,则类A当中可以不重写Shape中的抽象方法。
9、结合第八点,当A类再次被一个普通类C继承后,那么A和B这两个抽象类当中的抽象方法,C必须重写
class C extends A{
@Override
public void funcA(){
}
@Override
public void draw(){
}
}
我们定义一个新的普通类C,类C继承自抽象类A,而类A又是继承自类Shape,那么此时类C中需要重写类A和类Shape中的抽象方法。
10、抽象类不能被final修饰,抽象方法也不能
final修饰代表不可修改、不可继承的,因此,抽象类不能被final修饰,抽象方法也类似。
二、接口
1、使用interface 来修饰
interface Name{
}
代码格式如上
2、接口当中的普通方法,不能有具体的实现。非要实现,只能通过关键字default来实现
interface IShape{
public abstract void draw();//默认 public abstract
default public void func(){
System.out.println("默认方法");
}
}
3、接口当中可以有static方法
4、里面的所有方法都是public的
5、抽象方法默认是public abstract的
interface IShape{
void draw();//默认 public abstract
default public void func(){
System.out.println("默认方法");
}
}
与第2点的代码相比较,抽象方法前删除public abstract也可编译成功,系统默认抽象方法是public abstract的。
6、接口不可以通过关键字 new 来实例化
public static void main(String[] args) {
IShape iShape = new IShape() {
};
}
7、类和接口之间的关系是通过implements实现的
interface IShape{
public abstract void draw();//默认 public abstract
}
class Flower implements IShape {
@Override
public void draw() {
System.out.println("❀");
}
}
class Triangle implements IShape{
@Override
public void draw(){
System.out.println("△");
}
}
此时,我们写一个接口IShape,再写两个类Flower和Triangle,由代码段可以看到,两个类都是通过implements来实现接口的。
8、当一个类,实现了一个接口,就必须重写接口当中的抽象方法
在第7点代码段中,我们可以看到类Flower和类Triangle中都重写了接口IShape中的draw方法。
9、接口当中的成员,默认是public static final修饰的
interface IShape{
public abstract void draw();//默认 public abstract
default public void func(){
System.out.println("默认方法");
}
}
10、当一个类实现一个接口之后,重写这个方法的时候,这个方法前必须加public
因为接口里面的方法都是public,并且在实现的时候修饰范围不能缩小,所以只能是public
11、一个类可以通过extends继承一个抽象类或者普通类,但只能继承一个,同时,也可以通过implements实现多个接口
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void eat(){
System.out.println(name+"eat");
}
}
interface IJumping{
void jump();
}
interface ISwimming{
void swim();
}
class Flog extends Animal implements IJumping,ISwimming{
public Flog(String name) {
super(name);
}
@Override
public void jump(){
System.out.println(this.name+"正在跳");
}
@Override
public void swim(){
System.out.println(this.name+"正在游泳");
}
}
此时,我们定义了一个Animal类作为父类,定义两个接口→IJumping和ISwimming,此时子类Flog类继承自父类Animal并且实现了IJumping和ISwimming接口。在Flog类中,我们可以看到,重写了两个接口的抽象方法。
12、接口和接口之间存在的关系
接口和接口之间,使用extends来操作,此时意为:拓展
一个接口B通过extends来拓展另外一个接口A的功能,此时当一个类C实现了这个接口B的时候,此时重写的时候,不仅仅是B的抽象方法,还有他从A接口拓展来的功能
interface IJumping{
void jump();
}
interface Irunning extends IJumping{
void run();
}
class Cat extends Animal implements Irunning{
public Cat(String name){
super(name);
}
@Override
public void jump() {
System.out.println(this.name+"正在跳");
}
@Override
public void run() {
System.out.println(this.name+"正在跑");
}
}
public static void runFunc(Irunning irunning){
irunning.jump();
irunning.run();
}
runFunc(new Cat("王一鸣"));
此时,Irunning接口继承自IJumping接口,并且在Irunning接口中有其自己的抽象方法,此时来了一个Cat类实现了Irunning接口,那么在Cat类中就需要重写IJumping接口和Irunning接口中的抽象方法。
之后,通过在主函数声明一个静态runFunc方法,通过关键字new一个Cat实例。输出结果如下:
13、扩展知识
final关键字代表最终的、不可改变的
常见的四种用法:
①可以用来修饰一个类
作用:使当前这个类不能有任何子类
②可以用来修饰一个方法
作用:当final关键字用来修饰一个方法的时候,这个方法就是最终方法,不能够被覆盖重写
③可以用来修饰一个局部变量
作用:当fina关键字用于修饰局部变量的时候,这个局部变量就不能更改,“一次赋值,终生不变”。
④可以用来修饰一个成员变量
作用:用final修饰的成员变量不可变