JAVA面向对象 抽象类 接口 面向接口编程

1 抽象类

1.1 概念

Java中可以定义被abstract关键字修饰的方法,这种方法只有声明,没有方法体,叫做抽象方法.
Java中可以定义被abstract关键字修饰的类,被abstract关键字修饰的类叫做抽象类

  1. 如果一个类含有抽象方法,那么它一定是抽象类
  2. 抽象类中的方法实现交给子类来完成

1.2 抽象方法的格式

在这里插入图片描述

1.3 特点

  1. abstract 可以修饰方法或者类
  2. 被abstarct修饰的类叫做抽象类,被abstract修饰的方法叫做抽象方法
  3. 抽象类中可以没有抽象方法
  4. 如果类中有抽象方法,那么该类必须定义为一个抽象类
  5. 子类继承了抽象类以后,要么还是一个抽象类,要么就把父类的所有抽象方法都重写
  6. 多用于多态中
  7. 抽象类不可以被实例化

1.4 抽象类入门案例

/*本类用作抽象测试的入门案例*/
public class AbstractDemo {
    public static void main(String[] args) {
        /*4.抽象类不可以实例化!!!-创建对象*/
        //5.测试抽象父类是否可以创建对象
        //Animal a = new Animal();
        //6.创建多态对象进行测试
        Animal a = new Pig();
        a.eat();//调用抽象父类的普通方法
        a.fly();//调用抽象父类的抽象方法

    }
}
//1.创建父类Animal
/*2.被abstract修饰的类是抽象类
* 如果一个类中包含了抽象方法,那这个类必须被声明成一个抽象类*/
//4.2添加抽象方法后,本类需要用abstract修饰
abstract class Animal{
    //3.创建普通方法
    public void eat(){
        System.out.println("吃啥都行~");
    }
    public void play(){
        System.out.println("玩啥都行~");
    }
    //4.1创建抽象方法
    /*1.被abstract修饰的方法是抽象方法,抽象方法没有方法体*/
    public abstract void fly();
    public abstract void fly2();
}
//2.创建子类Pig,并与Animal类建立继承关系
/*3.当一个子类继承了抽象父类以后,有两种解决方案:
* 方案一:变成抽象子类,“躺平,我也不实现,继续抽象”
* 方案二:实现抽象父类中的所有的抽象方法,“父债子偿”*/
//4.3子类需要处理,继续抽象/实现父类所有抽象方法
//abstract class Pig extends Animal{--方案一
class Pig extends Animal{//方案二
    @Override//注解,标识这是一个重写的方法
    public void fly() {
        System.out.println("我爸的债我终于还清了,我家的猪终于飞起来了~");
    }

    @Override
    public void fly2() {
        System.out.println("抽象父类中的所有抽象方法都需要被实现");
    }

1.5 抽象类构造函数测试

/*本类用作抽象类构造函数测试*/
/*抽象类是否有构造方法?有
* 既然抽象类不能实例化,为什么要有构造方法呢?
* 不是为了自己使用,而是为了子类创建对象时使用super(); */
public class AbstractDemo2 {
    public static void main(String[] args) {
        //4.测试抽象类是否可以创建对象?不可以!!!
        //Animal2 a = new Animal2();
        //5.创建子类对象进行测试
        Pig2 p = new Pig2();
    }
}
//1.创建抽象父类Animal2
abstract class Animal2{
    //3.创建构造方法
    public Animal2(){
        System.out.println("我是Animal2的构造方法~");
    }
}
//2.创建子类Pig2
class Pig2 extends Animal2{
    //6.创建子类的无参构造
    public Pig2(){
        super();//表示调用父类的无参构造
        System.out.println("我是Pig2的构造方法~");
    }

1.6 抽象类成员测试

/*本类用作抽象类中的成员测试*/
public class AbstractDemo3 {
}
//1.创建抽象父类Fruit
abstract class Fruit{
    /*1.抽象类中可以定义成员变量吗?--可以!!!*/
    //3.1定义抽象父类中的成员变量
    int sum = 100;
    /*2.抽象类中可以定义成员常量吗?--可以!!!*/
    //3.2定义抽象父类中的成员常量
    final String name = "XIAOHUANGREN";
    /*3.抽象类中可以定义普通方法吗?--可以!!!
    * 抽象类中可以都是普通方法吗?--也可以!!!*/
    /*4.如果一类中都是普通方法,那它为啥还要被修饰成抽象类呢?
    * 因为抽象类不可以被实例化,所以如果不想让外界创建本类的对象
    * 就可以把普通类声明成抽象类*/
    //4.定义抽象父类的普通方法
    public void clean(){
        System.out.println("水果还是要洗洗再吃哒~");
    }
    /*5.抽象类中可以定义抽象方法吗?--可以!!!*/
    /*6.如果类中添加了抽象方法,那么这个类必须被声明成抽象类*/
    //5.定义抽象父类中的抽象方法
    public abstract void grow();
    public abstract void clean2();
}
//2.创建子类Banana
/*如果一个子类继承了抽象父类,有两种处理方案:
 1. 方案一:继续抽象,也就是作为抽象子类,无需实现抽象方法-"躺平"
 2. 方案二:不再抽象,实现继承自父类中的所有未实现的抽象方法-"父债子偿"*/
class Banana extends Fruit{
    @Override
    public void grow() {
        System.out.println("一串香蕉老沉了~");
    }
    @Override
    public void clean2() {
        System.out.println("香蕉不用洗,香蕉喜欢被扒皮");
    }

1.7 注意事项

抽象方法要求子类继承后必须重写。
那么,abstract关键字不可以和哪些关键字一起使用呢?以下关键字,在抽象类中。用是可以用的,只是没有意义了。
1.private:被私有化后,子类无法重写,与abstract相违背。
2.static:静态优先于对象存在,存在加载顺序问题。
3.final:被final修饰后,无法重写,与abstract相违背。

2 接口

2.1 接口的概念

与之前学习过的抽象类一样,接口( Interface )在Java中也是一种抽象类型,接口中的内容是抽象形成的需要实现的功能,接口更像是一种规则和一套标准.

2.2 接口格式

在这里插入图片描述

2.3 接口的特点

  1. 通过interface关键字来定义接口
  2. 通过implements让子类来实现接口
  3. 接口中的方法都是抽象方法(JAVA8)
  4. 可以把接口理解为一个特殊的抽象类(但接口不是类)
  5. 类描述的是一类事务的属性和方法,接口则是包含实现类要实现的方法
  6. 接口突破了java单继承的极限
  7. 接口和类直接可以多实现,接口与接口之间可以多继承
  8. 接口是对外暴露的规则,是一套开发规范
  9. 接口提高了程序的功能拓展,减低了耦合性(低耦合性是结构良好程序的特性,低耦合性程序的可读性及可维护性会比较好。)

2.4 练习创建

2.4.1 创建接口

package cn.tedu.inter;
/**本接口是创建接口测试*/
/**1.通过interface关键字来定义接口*/
public interface Inter {
	/**2.接口中可以有普通方法吗?--不可以!!*/
	//public void eat() {}
	
	/**3.接口中可以有抽象方法吗?--可以,接口中的方法都是抽象方法!!!*/
	public abstract void eat();
	public abstract void play();
}

2.4.2 创建接口实现类

package cn.tedu.inter;
/**本类作为Inter接口的实现类*/
/**1.实现类如果想用接口的功能,要和接口建立实现关系,通过关键字implements来实现*/
/**2.1 方案一:如果实现类与接口建立关系以后,可以选择不实现接口中的抽象方法,而是把自己变成一个抽象子类*/
//abstract public class InterImpl implements Inter{
/**2.2 方案二:如果实现类实现了接口以后,可以重写接口中的所有抽象方法*/
public class InterImpl implements Inter{

	@Override //作为标记,表示实现了父接口的抽象方法
	public void eat() {
		System.out.println("吃火锅");
	}

	@Override//作为标记,表示实现了父接口的抽象方法
	public void play() {
		System.out.println("玩代码");
	}

}

2.4.3 创建接口测试类

package cn.tedu.inter;
/**本类用于测试接口的实现类*/
public class InterTests {
	//6.创建入口函数main()
	public static void main(String[] args) {
		//7.测试接口创建对象
		/**接口可以创建对象吗?--不可以!!!*/
		//Inter i = new Inter();
		
		//8.创建多态对象进行测试
		Inter i = new InterImpl();
		//9.通过对象调用方法测试
		i.eat();
		i.play();
		
		//10.创建子类对象并进行测试
		InterImpl i2 = new InterImpl();
		i2.eat();
		i2.play();
	}
}

2.5.1 接口之构造方法

package cn.tedu.inter2;
/**本类用于进一步测试接口的使用*/
public class TestUserInter {
	//5.创建入口函数main()
	public static void main(String[] args) {
		//6.创建多态对象进行测试
		/**问题:子类创建对象时,默认会调用父类的构造方法
		 * 目前接口实现类的父级是一个接口,而接口没有构造方法
		 * 那实现类构造方法中的super()调用的是谁呢?
		 * 结论:如果一个类没有明确指定父类,那么默认继承顶级父类Object
		 * 所以super()会自动调用Object类中的无参构造
		 * */
		/**查看类的继承结构:Ctrl+T*/
		Inter2 i = new Inter2Impl();
	}
}

//1.创建接口
interface Inter2{
	/**1.接口中有构造方法吗?--不可以!!!*/
	//2.测试接口是否可以有构造方法
//	public Inter2() {}

}

//3.创建接口的实现类
//class Inter2Impl extends Object implements Inter2{
class Inter2Impl implements Inter2{
	//4.创建实现类的构造函数
	public Inter2Impl() {
		super();
		System.out.println("我是Inter2Impl的无参构造");
	}
}

总结:接口中是没有构造方法的
在创建对象时默认的super(),是调用的默认object的无参构造

2.5.2 接口之成员变量

package cn.tedu.inter2;
/**本类用于进一步测试接口的使用*/
public class TestUserInter {
	//5.创建入口函数main()
	public static void main(String[] args) {
		//6.创建多态对象进行测试
		/**问题:子类创建对象时,默认会调用父类的构造方法
		 * 目前接口实现类的父级是一个接口,而接口没有构造方法
		 * 那实现类构造方法中的super()调用的是谁呢?
		 * 结论1:如果一个类没有明确指定父类,那么默认继承顶级父类Object
		 * 所以super()会自动调用Object类中的无参构造
		 * */
		/**查看类的继承结构:Ctrl+T*/
		Inter2 i = new Inter2Impl();
		/**结论2:接口中的变量实际上都是静态常量,可以通过类名直接调用*/
		System.out.println(Inter2.age);
		/**结论3:接口中的变量实际上都是静态常量,值不可以被修改*/
		//Inter2.age = 200;
	}
}

//1.创建接口
interface Inter2{
	/**1.接口中有构造方法吗?--不可以!!!*/
	//2.测试接口是否可以有构造方法
//	public Inter2() {}
	/**2.接口里可以有成员变量吗?--没有!!!
	 * 是一个静态常量,实际上的写法是public static final int age = 10;
	 * 只不过在接口中可以省略不写
	 * */
	int age  = 10;

}

//3.创建接口的实现类
//class Inter2Impl extends Object implements Inter2{
class Inter2Impl implements Inter2{
	
	//4.创建实现类的构造函数
	public Inter2Impl() {
		super();
		System.out.println("我是Inter2Impl的无参构造");
	}
}

总结:接口里没有成员变量,都是常量。所以,你定义一个变量没有写修饰符时,默认会加上:public static final

2.5.3 接口之成员方法

package cn.tedu.inte2r;
/**本类用于进一步测试接口的使用*/
public class TestUserInter {
	public static void main(String[] args) {
		//3.在main()中创建多态对象进行测试
		/**问题:子类创建对象时,会自动调用父类的构造方法,但是现在的父级是个接口
		 * 接口里没有构造方法,那子类中super()调用的是什么呢?
		 * 结论1:子类默认继承了顶级父类Obejct,super()会自动调用Object的无参构造
		 */
		Inter2 in = new Inter2Impl();
		/**结论2.1:接口中的变量实际上都是静态常量,可以通过类名直接调用*/
		System.out.println(Inter2.age);
		/**结论2.2:接口中的变量实际上都是静态常量,不能被重新赋值*/
		//Inter2.age = 20;
	}
}

//1.创建接口
interface Inter2{
	/**1.接口里有构造方法吗?--没有!!!,连普通方法都没有*/
	//public Inter2() {}
	/**2.接口里可以有成员变量吗?--没有!!!*/
	int age = 10;//静态常量,实际上:final static int age = 10;
	/**3.接口中可以有抽象方法吗?--可以!!!*/
	abstract public void eat2();
	void eat();//可以简写--会自动拼接public abstarct
}
//2.创建接口的实现类
class Inter2Impl implements Inter2 {
	public Inter2Impl() {
		super();//默认先调用顶级父类Object的无参构造方法
		System.out.println("我是Inter2Impl的无参构造");
	}
	/**4.如果接口中添加了抽象方法,实现类中需要实现所有未实现的抽象方法*/
	@Override
	public void eat2() {
	}
	@Override
	public void eat() {
	}
}

总结:接口里的方法,默认就都是抽象的,如果你不写明是abstract的,那会自动补齐。例如:public abstract void save

2.6 面向接口编程

package cn.tedu.design;
/**本类用于改造老师设计案例,采用面向接口编程*/
public class TestDesignInter {
	public static void main(String[] args) {
		CGBTeacher2 ct = new CGBTeacher2();
		ct.ready();
		ct.teach();
	}
}
//1.创建接口Teacher2--抽取共性,形成抽象层-体现接口-定义的是规则
/**1.通过interface关键字定义接口*/
interface Teacher2{
	/**2.接口中的方法都是抽象方法,可以简写public abstract*/
	//2.定义接口中的抽象方法
	//2.1备课方法
	void ready();
	//2.2上课方法
	void teach();
}
/**3.如果实现类想要使用接口的功能,就需要与接口建立实现关系*/
//3.创建接口的实现类并添加所有未实现的方法
class CGBTeacher2 implements Teacher2{
	@Override
	public void ready() {
		System.out.println("正在备课...电商项目");
	}
	@Override
	public void teach() {
		System.out.println("正在上课...电商项目");
	}
}
//4.创建接口的抽象子类
abstract class SCDTeacher2 implements Teacher2{}

//5.创建接口的抽象子类2
abstract class ACTTeacher2 implements Teacher2{
	@Override
	public void ready() {
		System.out.println("正在备课...基础加强..框架加强..高新技术");
	}
	public abstract void teach() ;
}

2.7 接口的多继承多实现

package cn.tedu.design;
/**本类用于测试接口与类之间的复杂关系*/
public class TestRelation {
	//5.创建入口函数
	public static void main(String[] args) {
		//6.创建实现类对象进行测试
		Inter3Impl i3 = new Inter3Impl();
		i3.update();
		//7.创建多态对象进行测试
		Inter3 i4 = new Inter3Impl();
		i4.find();
	}
}
//1.创建接口1
interface Inter1{
	void save();//保存功能
	void delete();//删除功能
}
//2.创建接口2
interface Inter2{
	void update();//更新功能
	void find();//查询功能
}
//3.创建接口3用来测试接口与接口的继承关系
/**1.接口之间可以建立继承关系,而且还可以多继承
 * 接口与接口之间用逗号隔开
 * */
interface Inter3 extends Inter1,Inter2{
	
}
//4.创建Inter3接口的实现类并添加未实现的方法
/**2.接口和实现类之间可以建立实现关系,通过implments关键字来完成
 * 注意,java类是单继承,而接口不限,写接口时,我们一般先继承再实现
 * */
class Inter3Impl implements Inter3{
	@Override
	public void save() {
		System.out.println("稍等...正在保存中...");
	}
	@Override
	public void delete() {
		System.out.println("稍等...正在删除中....");
	}
	@Override
	public void update() {
		System.out.println("客官,马上就更新好啦~~");
	}
	@Override
	public void find() {
		System.out.println("小二正在马不停蹄的查询~~~");
	}
}

2.8 总结

2.8.1 类与类的关系

继承关系,只支持单继承
比如,A是子类 B是父类,A具备B所有的功能(除了父类的私有资源和构造方法)
子类如果要修改原有功能,需要重写(方法签名与父类一致 + 权限修饰符>=父类修饰符)

2.8.2 类与接口的关系

实现关系.可以单实现,也可以多实现
class A implements B,C{}
其中A是实现类,B和C是接口,A拥有BC接口的所有功能,只是需要进行方法的重写,否则A就是抽象类

2.8.3 接口与接口的关系

是继承关系,可以单继承,也可以多继承
interface A extends B,C{}
其中ABC都是接口,A是子接口,具有BC接口的所有功能(抽象方法)
class X implements A{}
X实现类需要重写ABC接口的所有方法,否则就是抽象类
class A extends B implements C,D{}
其中A是实现类,也是B的子类,同时拥有CD接口的所有功能
这时A需要重写CD接口里的所有抽象方法

2.8.4 抽象类与接口的区别

抽象类是一个特殊的类,特殊在,抽象类中可以包含没有方法体的方法(抽象方法)
接口可以理解成一个特殊的抽象类,特殊在,接口里的都是抽象方法,没有普通方法
接口会为方法自动拼接public abstract,还会为变量自动拼接public final static
抽象类可以有构造方法–用来给子类创建对象,接口中没有构造方法
抽象类和接口都不能实例化(创建对象)
接口可继承接口,并可多继承接口,但类只能单继承
抽象方法只能声明,不能实现,接口是设计的结果 ,抽象类是重构的结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值