1.抽象方法、抽象类
1)抽象方法:
- 由abstract修饰
- 只有方法的定义,没有方法的具体实现(连{}都没有)
由abstract修饰的方法为抽象方法,抽象方法只有方法的定义,没有方法体实现,用一个分号结尾。即:方法五要素中,抽象方法缺少了一个要素(方法体),也可以将抽象方法理解为不完整的方法。
2)抽象类:
- 由abstract修饰
- 包含抽象方法的类必须是抽象类,不包含抽象方法的类也可以声明抽象类(意义不大)
- 抽象类不能被实例化
- 抽象类是需要被继承的
-
- 子类需要重写抽象类的所有抽象方法---常用
- 子类也可以声明为抽象类---不常用
-
- 抽象类的意义:
-
- 封装子类所共有的属性和行为---代码复用
- 为所有子类提供一种统一的类型---向上造型
- 可以包含抽象方法,为所有子类提供了统一的入口,子类的实现不同,但入口是一致的
-
由abstract修饰的类为抽象类,抽象类是不能实例化对象的,而一个类不能实例化是没有意义的,所以需要定义类来继承抽象类,它的子类必须重写所有的抽象方法,除非该类也声明为抽象类。
abstract class Foo{ private double c; public Foo(double c){ //没什么意义,需要被子类重写 this.c = c; } public abstract double area(); //抽象方法,没有方法体,大括号也不存在 } class Sub extends Foo{ public Sub(double c) { //需要重写构造方法 super(c); } public double area(){ return 0.0; } } abstract class Sub2 extends Foo{ //抽象方法继承抽象方法 public Sub2(double c) { //需要重写构造方法,不需要重写抽象方法 super(c); } }
3)抽象类不可以被实例化
Foo f = new Foo(); //编译错误,抽象类不能被实例化
即使一个类中没有抽象方法,也可以将其定义为抽象类,同样,该类不可以实例化。
注意:abstract和final关键字不能同时修饰一个类,因为final使得类不可继承,而abstract修饰的类如果不可以继承将没有任何意义。
4)继承抽象类
一个类继承抽象类后,必须实现其抽象方法,不同的子类可以有不同的实现。
abstract class Foo{ private double c; public Foo(double c){ //没什么意义,需要被子类重写 this.c = c; } public abstract String sayHi(); } class Sub extends Foo{ public Sub(double c) { //需要重写构造方法 super(c); } public String sayHi(){ return "Hello"; } }
4)抽象类的意义
- 为其子类提供一个公共的类型(父类引用指向子类对象,即向上造型)
- 封装子类中的重复内容(成员变量和方法)
- 定义有抽象方法,子类虽然有不同的实现,但该方法的定义是一致的(子类需要实现此抽象方法)
案例1:抽象类演示
public class AbstractDemo { public static void main(String[] args){ // Shape s = new Shape(); //编译错误,抽象类不能被实例化 Shape[] shape = new Shape[4]; //创建Shape数组对象 shape[0] = new Circle(1); //向上造型 shape[1] = new Circle(2); shape[2] = new Square(1); shape[3] = new Square(2); maxArea(shape); //调用求最大面积方法 } private static void maxArea(Shape[] shape) { double max = shape[0].area(); int maxIndex = 0; //最大面积下标 for(int i=0;i<shape.length;i++){ double area = shape[i].area(); if(area>max){ max = area; maxIndex=i; } } System.out.println("最大面积为:"+max+"所在下标为:"+maxIndex); } } abstract class Shape{ //抽象类---不完整的类 protected double c; //周长 public abstract double area(); //抽象方法---不完整 } class Circle extends Shape{ public Circle(double c){ this.c = c; } public double area(){ //重写抽象方法---变不完整为完整 return 0.0796*c*c; } } class Square extends Shape{ public Square(double c){ this.c = c; } public double area(){ return 0.0625*c*c; } }
2. 接口
- 是一个标准、规范,遵循了这个标准就能干某件事
- 是一种数据类型(引用类型)
- 由interface定义,只能包含常量和抽象方法,方法默认由public abstract修饰
- 接口不能被实例化
- 接口是需要被实现的,通过implements关键字实现,实现类:必须重写接口中的所有抽象方法
- 一个类可以实现多个接口,逗号分隔,若又继承又实现,必须先继承后实现
- 接口可以继承一个或多个接口,逗号分隔(extends)
1)定义接口
接口可以看成是特殊的抽象类。即:只包含抽象方法和常量的抽象类。通过interface关键字来定义接口。
interface Demo{ public static int x = 100; public int y = 50; double area(); //默认会加上public abstract修饰 public abstract void test(); }
2)实现接口
与继承不同,一个类可以实现多个接口,实现的接口直接用逗号分隔,该类需要实现这些接口中定义的所有方法。通过implements关键字实现接口。接口可以作为一种类型声明变量,一个接口类型的变量可以引用实现了该接口的类的对象,通过该变量可以调用该接口中定义的方法(具体的实现类提供了方法的实现)。一个接口类型变量,引用了子类的对象,调用时,调用的是子类对象的具体的实现。
public class Test { public static void main(String[] args){ Demo d = new Aoo(); //一个接口类型变量,引用了子类的对象,调用时,调用的是子类对象的具体的实现 d.test(); //This is Aoo } } interface Demo{ public static int x = 100; public int y = 50; double area(); //默认会加上public abstract修饰 public abstract void test(); } class Aoo implements Demo{ public double area(){ return 0.0; } public void test(){ System.out.println("This is Aoo"); } }
3)接口的继承
接口间可以存在继承关系,一个接口可以通过extends关键字继承另外一个接口,子接口继承了父接口中定义的所有方法。
interface Foo{ public void funFoo(); } interface Goo{ public void funGoo(); } interface Hoo extends Foo,Goo{ //接口可以继承一个或多个接口,逗号分隔 public void funHoo(); } interface Ioo{ void funIoo(); } class Joo implements Hoo,Ioo{ //一个类可以继承多个接口 public void funFoo(){} //重写父类的父类的抽象方法 public void funGoo(){} //重写父类的父类的抽象方法 public void funHoo(){} //重写父类的抽象方法 public void funIoo(){} //重写父类的抽象方法 }
4)接口和抽象类的区别
- 一个类只能继承一个抽象类,但可以实现多个接口
- 抽象类中可以包含抽象方法和非抽象方法,而接口中的所有方法均为抽象的
- 子类继承抽象类必须实现抽象类中所有抽象方法,否则子类也必须是抽象类。而子类实现接口则必须实现接口中所有的抽象方法。
案例2:接口的演示
public class InterfaceDemo { public static void main(String[] args){ // Inter6 o1= new Inter6(); //编译错误,接口不能被实例化 Inter6 o2 = new Moo(); //向上造型 Inter5 o3 = new Moo(); } } //演示接口语法 interface Inter1{ public static final int NUM = 5; public abstract void show(); double PI = 3.14; //默认public static final修饰 void say(); //默认public abstract修饰 // int count; //编译错误,常量必须声明同时初始化 // void test(){} //编译错误,抽象方法没有方法体 } //演示接口实现 interface Inter2{ void show(); void say(); } class Joo implements Inter2{ public void show(){} public void say(){} } //演示接口的多实现、继承 interface Inter3{ void show(); } interface Inter4{ void say(); } abstract class Koo{ abstract void test(); } class Loo extends Koo implements Inter3,Inter4{ public void show(){} public void say(){} void test(){} } //演示接口继承接口 interface Inter5{ void show(); } interface Inter6 extends Inter5{ void say(); } class Moo implements Inter6{ public void show(){} public void say(){} }
时间: 2024-10-14 09:49:06