问题一:能不能去掉父类中被重写方法的执行语句?
问题二:能不能去掉父类中被重写的方法?
问题一:
class Person{
public void run(); //去掉执行语句
}
问题二:
class Person{
//去掉被重写的方法
}
public void runTwice(Person p){
p.run()
}
结果是都会报编译错误
1、抽象类和abstract关键字- 如果一个类定义了方法,但没有任何执行语句,这个方法就是抽象方法 用abstract修饰
- 抽象类和抽象方法是一起的,因为普通的类无法执行抽象方法,需要把类定义成抽象类
- 抽象类无法被实例,只能用来被继承,而且强迫子类重写抽象方法
- 上层代码只负责定义规范
- 不需要实现功能(定义子类)即可实现逻辑(可以编译)
- 可以有不同的子类去重写方法,从而调用不同的子类实现不同的逻辑
main.java
package abstractclass;
public class main {
public static void main(String[] args) {
// TODO: 用抽象类给一个有工资收入和稿费收入的小伙伴算税:
Income[] incomes = new Income[]{ new SalaryIncome(7500), new RoyaltyIncome(12000)};
//Income[] incomes = new Income[] { new Income(3000), new SalaryIncome(7500), new RoyaltyIncome(12000) };
double total = 0;
//
for (Income income:incomes)
total += income.getTax();
System.out.println(total);
}
}
Income.java
package abstractclass;
public abstract class Income {
protected double salary;
public Income(double salary){
this.salary = salary;
}
abstract double getTax(); //定义了抽象方法
}
RoyaltyIncome.java
package abstractclass;
public class RoyaltyIncome extends Income {
//稿费收入税率是20%
public RoyaltyIncome(double salary)
{
super(salary);
}
@Override
public double getTax(){
return salary * 0.2;
}
}
SalaryIncome.java
package abstractclass;
public class SalaryIncome extends Income {
public SalaryIncome(double salary){
super(salary);
}
@Override
public double getTax()
{
if(salary <= 5000)
return 0;
else{
return (salary - 5000) * 0.2;
}
}
}
二、接口
抽象类中上层类实际上定义了一个规范,规范了子类的调用,如果一个抽象类中没有字段,所有的方法都是抽象方法,就可以把抽象类改写为接口(interface)
1、声明用interface声明一个抽象类,里面的方法都是抽象方法(省略 public abstract)
interface Person{
void run();
String getName();
}
当一个具体的类实现接口时,用implements
class Student implements Person, Hello{
//注意一个类只能继承另一个类,但是可以实现多个接口
}
注意:Java的接口特指interface的定义,表示一个接口类型和一组方法签名,而编程接口泛指接口规范,如方法签名,数据格式,网络协议等
2、继承与接口的比较| abstract class | interface | |
|---|---|---|
| 继承 | 只能extends一个class | 可以implements多个interface |
| 字段 | 可以定义实例字段 | 不能定义实例字段 |
| 抽象方法 | 可以定义抽象方法 | 可以定义抽象方法 |
| 非抽象方法 | 可以定义非抽象方法 | 可以定义default方法 |
一个接口可以继承另一个接口(用extends实现),相当于扩展接口的方法
interface Hello{
void hello();
}
interface Person extends Hello{
void run();
String getName();
}
4、继承关系
合理设计interface与abstract class的继承关系,可以充分复用代码
例子:java的集合类定义的一组接口,抽象类和具体子类的继承关系
5、default方法default修饰方法只能在接口中使用,在接口中被default标记的方法为普通方法,可以直接写方法体,也就是说能在default方法里面写代码
-
实现类会继承接口中的default方法
-
如果一个类同时实现接口A和B, 接口A和B中有相同的default方法,该类必须重写default方法,否则不知道从哪个接口继承default方法
-
如果一个类继承 另一个类A和实现一个接口B,A中有与B 的default相同的方法,这个类会去继承A中的方法,而不是接口中的default方法
Main.java
package Interface;
public class Main {
public static void main(String[] args) {
// TODO: 用接口给一个有工资收入和稿费收入的小伙伴算税:
Income[] incomes = new Income[] { new SalaryIncome(7500), new RoyaltyIncome(12000) };
//Income[] incomes = new Income[] { new Income(3000), new SalaryIncome(7500), new RoyaltyIncome(12000) };
double total = 0;
// TODO:
for (Income income: incomes){
total += income.getTax();
}
System.out.println(total);
}
}
Income.java
package Interface;
public interface Income {
//定义接口
double getTax();
//定义接口中的方法
}
RoyaltyIncome.java
package Interface;
public class RoyaltyIncome implements Income {
protected double salary;
public RoyaltyIncome(double salary){
this.salary = salary;
}
@Override
public double getTax(){
return salary * 0.2;
}
}
SalaryIncome.java
package Interface;
public class SalaryIncome implements Income{
protected double salary;
public SalaryIncome(double salary){
this.salary = salary;
}
public double getTax(){
if (this.salary <= 5000){
return 0;
}
else{
return (salary - 5000) * 0.15;
}
}
}



