Java拾贝不建议作为0基础学习,都是本人想到什么写什么
如果父类的方法本身不需要实现,仅仅是为了定义方法。
目的是让子类去重写它,那么,可以把父类的方法声明为抽象(abstract)方法
class Candy {
public abstract void sell();
}
//无法通过编译
若某类中拥有一个或若干个抽象方法,其类也必须声明为抽象(abstract)类
abstract class Candy {
int i;//抽象类中可以有属性
public abstract void sell();
public void buy();//抽象类中可以有普通方法
}
抽象类
如果一个类定义了方法,却没有方法的具体实现,那么该方法可以声明为抽象方法。
其类也必须声明为抽象类。
用abstract修饰的类就是抽象类,无法实例化一个抽象类。
Candy candy = new Candy();//无法通过编译
那有什么用?事实上,抽象类强迫子类必须重写其内部的抽象方法。
所以抽象类可以被视作"模具"/"规范"/"模板"
在多态性得知,方法实际运行效果看子类的具体实现(基于子类重写)
public class test5 {
public static void main(String[] args) {
Candy candy = new SmallCandy();//向上转型
candy.sell();
}
}
abstract class Candy {
public abstract void sell();
}
class SmallCandy extends Candy{
@Override
public void sell() {
System.out.println("抽象类设计初始专门用于被继承的子类重写");
}
}
//抽象类设计初始专门用于被继承的子类重写
抽象类可以拥有属性和普通方法,只要不涉及到抽象方法,可以把抽象类当作普通类去使用。
//向上转型勿忘 属性看对象,方法看指向。
public class test5 {
public static void main(String[] args) {
Candy c=new SmallCandy();
c.i=10;
System.out.println(c.i);
System.out.println(c.getI());
c.say();
c.sell();
}
}
abstract class Candy {
int i;
abstract void sell();
void say() {
System.out.println(getI());
}
int getI() {
return this.i+10;
}
}
class SmallCandy extends Candy{
@Override
void sell() {
System.out.println(i);
}
}
/*
10
20
20
10
*/
抽象编程
当我们定义了抽象类Candy,以及具体实现的SamllCandy、BigCandy或更多子类时
可以通过抽象类去指向子类实例。(向上转型)
Candy sc = new SmallCandy();
Candy bc = new BigCandy();
同样的,如果再新增一个子类,我们也不用去关心其具体的对象类型,直接使用向上转型。
Candy sc = new MiddleCandy();
这种尽量使用高层对象(继承关系的高层),避免使用其子类本身的编程方式称之为抽象编程
接口
如果一个抽象类中所有方法都是抽象方法,也没有定义属性。
abstract class Candy {
public abstract void sell();
public abstract void buy();
}
那么该抽象类可以改写为接口(interface)
interface Candy {
void sell();
public abstract void buy();
//在接口中,所有方法默认public abstract,加了也不影响。
}
当一个类要去实现接口时,使用implements关键字。(该类也被称为实现类)
interface Candy {
void sell();
void buy();
}
class SmallCandy implements Candy {
@Override
public void sell() {
System.out.println("实现接口的类称之为实现类");
}
@Override
public void buy() {//接口默认都是抽象方法,必须全部重写
}
}
我们知道在Java中,只允许继承一个类
class Sub extends Base{}
但是允许实现多接口
class Sub extends Base implements Candy,SmallCandy,...{}
接口继承
接口也可也使用继承,与类的继承特点相同。
interface Candy {
void sell();
}
interface SmallCandy extends Candy {
void buy();
}
此时,SmallCandy接口现有2个抽象方法,其中1个来自继承的Candy。
相同的,实现类P也要重写2个方法。
class P implements SmallCandy{
@Override
public void sell() {
}
@Override
public void buy() {
}
}
default方法
如果要给接口新增一个方法时,会设计到全部子类,那么就可以使用defaul方法。
就可以不必去全部修改,只需要在继承树关系最高级的接口中新增defaul方法即可。
public class test5 {
public static void main(String[] args) {
Candy c=new P();//向上转型
c.say();
SmallCandy s =new P();
s.say();//变量c和s都可以调用到say方法
}
}
class P implements SmallCandy {
@Override
public void sell() {
}
@Override
public void buy() {
}
}
interface Candy {
default void say(){
System.out.println("default方法就是这个作用哒!");
}
void sell();
}
interface SmallCandy extends Candy {
void buy();
}
default方法和抽象类的普通方法是有所不同的。因为interface没有属性,default方法无法访问属性,而抽象类的普通方法可以访问属性。
抽象类与接口的不同
抽象类 | 接口 | |
---|---|---|
继承 | 只能extends一个类 | 可以implements多个接口 |
属性 | 可以存在属性 | 不能存在属性 |
抽象方法 | 可以定义抽象方法 | 可以定义抽象方法 |
非抽象方法 | 可以定义普通方法 | 可以定义default方法 |