抽象类与接口

抽象类与接口

抽象类:

  1. 抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体
abstract class A{//定义一个抽象类
	
	public void fun(){//普通方法
		System.out.println("存在方法体的方法");
	}
	
	public abstract void print();
    //抽象方法,没有方法体,有abstract关键字做修饰
	
}
  1. 抽象类不能被实例化,无法使用new 关键字来调用抽象类的构造器创建抽象类的实例,即使抽象类里不包含抽象方法,这个抽象类也不能创建实例。
abstract class A{//定义一个抽象类
	
	public void fun(){//普通方法
		System.out.println("存在方法体的方法");
	}
	
	public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
	
}

public class TestDemo {

	public static void main(String[] args) {
		A a = new A();
        //会报错
	}
}
  1. 抽象类可以包含成员变量,方法(普通方法和抽象方法都可以),构造器,初始化块,内部类(接口,枚举)5种成分。抽象类的构造方法不能用于创建实例,主要是用于被其子类调用。
public abstract class Shape {
    {
        System.out.println("执行Shape的初始化块");
    }
    interface Inner{
        //内部类
    }
    private String color;
    public abstract double calPerimeter();
    public String talk(){
        return "普通方法";
    };

    public Shape(){ };

    public Shape(String color) {
        System.out.println("这是构造器");
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}
  1. 含有抽象方法的类(包括直接定义一个抽象类方法,或继承了一个抽象父类,但没有完全实现父类包含的抽象方法,或实现了一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类

比如说:父类是水果一个大类,有水果的名字,食用水果两个方法。其中水果的名字为抽象方法,食用水果为一个普通方法,香蕉和苹果是水果这一大类中的子类,但香蕉必须重写父类水果的名字为香蕉,食用水果方法可以直接调用。对于苹果必须重写父类水果的名字为苹果,食用水果方法可以直接调用。

简单来说就相当于父类是英语范文挖出来一堆的空位置语句,而子类就相当于你和别同学去填写这个模板中的各种空位置的语句,结果是填的不一样,而造成了不一样的的文章,这样就形成了两个不一样的东西。

abstract class A{//定义一个抽象类
	
	public A(){
		System.out.println("*****A类构造方法*****");
	}

	public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
	
}
//单继承
class B extends A{//B类是抽象类的子类,是一个普通类

	public B(){
		System.out.println("*****B类构造方法*****");
	}
	
	@Override
	public void print() {//强制要求覆写
		System.out.println("Hello World !");
	}
	
}
public class TestDemo {

	public static void main(String[] args) {
       // 抽象类,不能实例化,必须需要子类进行实例化
		A a = new B();//向上转型
	}

}

当使用abstract修饰类时,表明这个类只能被继承;当使用abstract修饰方法时,表明这个方法需由子类重写,而final修饰方法不能被重写,因此两者从来不能被同时使用

抽象类的作用:

  1. 抽象父类可以只定义需要使用的某些方法,把不能实现的部分抽象成为方法,留给其子类去实现;
  2. 父类中可能包含需要调用其他系列方法的方法,这些被调用即可以由父类实现,也可以有其子类实现。父类里提供的方法只是定义了一个通用算法,其实现也许并不完全有自身实现,而必须依赖于其子类的辅助。

接口的概念:

和类的定义不同,定义接口不再使用class关键字,而是使用了interface关键字,接口的定义语法如下

[修饰符] interface 接口名 extends 父接口1, 父接口2...{
    零个到多个常量定义。。。
        
}
interface Power {
    
}
  1. 修饰符可以是public 或者省略,如果省略了public 访问控制符,则默认采用包权限访问控制符,即只有在相同包结构下才可以访问该接口。
  2. 接口应该于类名采用相同的规范
  3. 一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类。

接口里面定义的内部类,内部接口,内部枚举默认都采用public static两个修饰符,不管定义是否指定这两个修饰符,系统都会自动使用public static 对它们进行修饰。

public interface Output {

    int MAX_CACHE_LIME = 50;
    //需要重写
    void out();
    //需要重写
    void getData(String msg);
    
    default void print(String... msgs){
        for (String msg : msgs){
            System.out.println(msg);
        }
    }
    default void test(){
        System.out.println("默认的test()方法");
    }
    static String staticTest(){
        return "接口里的类方法";
    }
    //不能调用
    private void foo(){
        System.out.println("jdk11以后出现在接口里面有private");
    }
    private static void bar(){
        System.out.println("bar私有静态方法");
    }
    //只有接口中可以调用私有方法
    public static void main(String[] args) {
        bar();
    }
}
public class S {
    //需要重写才可以调用,相对应的方法
    @Override
    public void out() {
        
    }

    @Override
    public void getData(String msg) {

    }

    @Override
    public void print(String... msgs) {
        Output.super.print(msgs);
    }

    @Override
    public void test() {
        Output.super.test();
    }
    public static void main(String[] args) {
        System.out.println(Output.MAX_CACHE_LIME);
        System.out.println(Output.staticTest());

    }
}

接口的继承:

接口的继承和类继承不一样,接口完全支持多继承,即一个接口可以有多个直接父类。和继承相似,子接口扩展某个父接口,将会获得父接口里定义的锁有抽象方法,常量。

interface InterfaceA{
    int PROP_A = 5;
    void testA();
}
interface InterfaceB{
    int PROP_B = 6;
    void testB();
}
interface InterfaceC extends InterfaceA, InterfaceB{
    int PROP_C = 7;
    void testC();
}
public class InterfaceExtendsTest {
    public static void main(String[] args) {
        System.out.println(InterfaceC.PROP_A);
        System.out.println(InterfaceC.PROP_B);
        System.out.println(InterfaceC.PROP_C);
    }
}

使用接口:

接口不能用于创建实例,但接口可以用于声明引用类型变量。当使用接口来声明引用类型变量时,这个引用类型变量必须引用到其实现类的对象.除此之外,接口的主要用途就是被实现类实现.归纳起来,接口主要有如下用途:

  1. 定义变量,也可以用于进行强制类型转换。
  2. 调用接口中定义的常量
  3. 被其他类实现。
interface Product{
    int getProduceTime();
}

public class Printer implements Output, Product {
    private String[] printData
            = new String[MAX_CACHE_LIME];
    private int dataNum = 0;
    public void out(){
        while (dataNum>0){
            System.out.println("打印机大印: "+printData[0]);
            System.arraycopy(printData,1,printData,0,--dataNum);
        }
    }
    public void getData(String msg){
        if (dataNum >= MAX_CACHE_LIME){
            System.out.println("输出队列已满,添加失败");
        }else{
            printData[dataNum++] = msg;
        }
    }
    @Override
    public int getProduceTime() {
        return 45;
    }

    public static void main(String[] args) {
        Output o = new Printer();
        
        o.getData("轻量级Java EE 企业应用实战");
        o.getData("疯狂java讲义");
        o.out();
        o.getData("疯狂Android讲义");
        o.getData("疯狂Ajax");
        o.out();
        o.print("孙悟空","猪八戒","白骨精");
        o.test();
        
        Product p = new Printer();
        System.out.println(p.getProduceTime());
        
        Object obj = p;
    }
}

接口和抽象类

共同特征

  1. 接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。
  2. 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。

不同:

  1. 接口里只能包含抽象方法,静态方法,默认方法和私有方法,不能为普通方法提供方法实现;抽象类则完全可以包含普通方法。
  2. 接口里只能定义静态常量,不能定义普通成员变量,抽象类里则即可以定义普通成员变量,也可以定义静态常量。
  3. 接口不包含构造器,抽象类可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。
  4. 接口里面不能包含初始化块;但抽象类则可以完全包含初始化块。
  5. 一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补java单继承的不足。
    )
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值