抽象类
概念
- Java中可以定义被abstract关键字修饰的方法,这种方法只有声明,没有方法体,叫做抽象方法.
- Java中可以定义被abstract关键字修饰的类,被abstract关键字修饰的类叫做抽象类
- 如果一个类含有抽象方法,那么它一定是抽象类
- 如果一个类是抽象类,那么它可以不含有抽象方法
- 抽象类中的方法实现交给子类来完成(不写方法体是为了满足各个子类对该方法执行不同的行为)
抽象方法的格式:
权限修饰符 abstract 返回值类型 方法名(参数列表);
特别注意:抽象方法没有方法体
特点
- abstract 可以修饰方法或者类
- 被abstarct修饰的类叫做抽象类,被abstract修饰的方法叫做抽象方法
- 抽象类中可以没有抽象方法
- 如果类中有抽象方法,那么该类必须定义为一个抽象类
- 子类继承了抽象类以后,要么还是一个抽象类,要么就把父类的所有抽象方法都重写
- 多用于多态中
- 抽象类不可以被实例化(不能创建对象),可以使用多态
注意:
当一个子类继承了抽象父类以后,有两种解决方案: 1.变成抽象子类,"躺平,我也不实现,继续抽象" 2.重写父类中所有的抽象方法,"父债子偿",注意是所有
package cn.tedu.test1; public class AbstractDemo { public static void main(String[] args) { // Animal a = new Animal(); //抽象类不能实例化(不能创建对象) Pig pig = new Pig(); //在这里Pig类不是抽象类 Animal animal = new Pig(); //可以使用多态 animal.fly(); animal.fly2(); } } abstract class Animal{ //定义一个抽象类 public void eat(){ //抽象类可以定义普通方法 System.out.println("吃啥都行~"); } public void play(){ System.out.println("玩啥都行~"); } public abstract void fly(); //定义抽象方法,注意抽象方法没有方法体 public abstract void fly2(); //定义抽象方法 } //当一个子类继承了抽象父类以后,有两种解决方案: //1.变成抽象子类,"躺平,我也不实现,继续抽象" //2.重写父类中所有的抽象方法,"父债子偿" class Pig extends Animal{ @Override public void fly(){ //重写父类所有抽象方法 System.out.println("猪也能飞"); } @Override public void fly2(){ //重写父类所有抽象方法 System.out.println("母猪也能上树"); } } //abstract class Pig extends Animal{}//变成抽象子类 结果显示: 猪也能飞 母猪也能上树
抽象类构造函数测试
1.抽象类中可以有构造方法 2.父类的构造方法要优先于子类执行 3.抽象类不可以创建对象(实例化) 4.抽象类中存在的构造方法不是为了创建本类对象时调用 而是为了创建子类对象时使用(一切为了孩子)
package cn.tedu.test1; /* * 1.抽象类中可以有构造方法 * 2.父类的构造方法要优先于子类执行 * 3.抽象类不可以创建对象(实例化) * 4.抽象类中存在的构造方法不是为了创建本类对象时调用 * 而是为了创建子类对象时使用 * */ public class AbstractDemo2 { public static void main(String[] args) { // Animal2 a = new Animal2();//抽象类不可以实例化 Pig2 pig2 = new Pig2();//抽象类中的构造函数通常在子类对象实例化时使用 pig2.eat(); } } abstract class Animal2{ public Animal2(){ //抽象父类创建构造方法不是为了自己使用,而是为了子类创建对象时使用 System.out.println("我是Animal2的构造方法"); } public abstract void eat(); } class Pig2 extends Animal2{ public Pig2(){ // super();//默认存在父类的构造方法 System.out.println("我是Pig2的构造方法"); } public void eat(){ System.out.println("猪猪吃猪料"); } } 结果显示: 我是Animal2的构造方法 我是Pig2的构造方法 猪猪吃猪料
抽象类成员测试
抽象类中可以定义普通方法且可以都是普通方法 问题:如果一个类里面都是普通方法,那为什么还要被修饰成抽象类? 答:因为抽象类不可以被实例化,所以如果不想让外界创建本类的对象,就可以把普通类声明成抽象类
package cn.tedu.test1; public class AbstractDemo3 { public static void main(String[] args) { Fruit fruit = new Banana(); System.out.println(fruit.name); fruit.eat(); fruit.clean(); } } abstract class Fruit{ //抽象类中可以定义成员变量 int sum = 100; //抽象类中可以定义成员常量 final String name = "zll"; //注意final修饰的常量要初始化 //抽象类中可以定义普通方法且可以都是普通方法 //如果一个类里面都是普通方法,那为什么还要被修饰成抽象类? //因为抽象类不可以被实例化,所以如果不想让外界创建本类的对象,就可以把普通类声明成抽象类 public void eat(){ System.out.println("水果好吃"); } public abstract void clean(); } class Banana extends Fruit{ @Override public void clean(){ System.out.println("香蕉不用洗"); } } 结果显示: zll 水果好吃 香蕉不用洗
抽象类综合使用案例
package cn.tedu.design; /*设计老师类,要求:面向抽象编程--后天向上抽取形成的结果(先把各类老师需要的属性、方法都老实写出来,然后才发现这些共同的属性和方法,才向上抽取这些共性,形成规则)*/ public class DesignTeacher1 { public static void main(String[] args) { CGBTeacher ct = new CGBTeacher(); ct.ready(); ct.teach(); ACTTeacher at = new ACTTeacher(); at.ready(); at.teach(); SCDTeacher st = new SCDTeacher(); st.ready(); st.teach(); } } abstract class Teacher{ //创建老师类,为各类老师的父类,提取所有老师的共性,减少代码的冗余 String name;//姓名 int id;//工号 // public void teach(){ //改变各类老师的讲课内容,就需要用到抽象方法 // System.out.println("正在讲课"); // } public abstract void teach(); // public void ready(){ //改变各类老师的备课内容 // System.out.println("正在备课"); // } public abstract void ready(); } //1.创建培优老师类 class CGBTeacher extends Teacher{ @Override public void teach() { System.out.println("CGB正在讲课...CGB"); } @Override public void ready() { System.out.println("CGB正在备课...CGB"); } } class ACTTeacher extends Teacher{ @Override public void teach() { System.out.println("ACT正在讲课...ACT"); } @Override public void ready() { System.out.println("ACT正在备课...ACT"); } } class SCDTeacher extends Teacher{ @Override public void teach() { System.out.println("SCD正在讲课...SCD"); } @Override public void ready() { System.out.println("SCD正在备课...SCD"); } }结果显示:
CGB正在备课...CGB
CGB正在讲课...CGB
ACT正在备课...ACT
ACT正在讲课...ACT
SCD正在备课...SCD
SCD正在讲课...SCD
接口
概念
与抽象类一样,接口( Interface )在Java中也是一种抽象类型,接口中的内容是抽象形成的需要实现的功能,接口更像是一种规则和一套标准.
接口可以看作是一个特殊的抽象类,因为它里面全是抽象方法。
接口格式
修饰符 interface 接口名{ 代码... }
特点
- 通过interface关键字来定义接口
- 通过implements让子类来实现接口
- 接口中的方法全部都是抽象方法(JAVA8)
- 可以把接口理解成一个特殊的抽象类(但接口不是类!!!)
- 类描述的是一类事物的属性和方法,接口则是包含实现类要实现的方法
- 接口突破了java单继承的局限性
- 接口和类之间可以多实现,接口与接口之间可以多继承
- 接口是对外暴露的规则,是一套开发规范
- 接口提高了程序的功能拓展,降低了耦合性
接口使用
1.创建接口
package cn.tedu.inter; /*本接口用于接口创建测试 通过interface关键字来定义接口 */ public interface Inter { /*接口中不可以定义普通方法*/ // public void eat(){} /*接口中的方法都是抽象方法*/ public abstract void eat(); public abstract void play(); }
2.创建接口实现类
package cn.tedu.inter; /*本类作为Inter接口的实现类*/ /*1.实现类如果想要和接口建立实现关系,通过implements来实现*/ /*2.接口实现类与接口建立关系之后,有两种解决方案: * 方案一:作为抽象子类,不实现任何抽象方法 * 方案二:作为普通子类,实现父级接口中所有的抽象方法*/ //abstract public class InterImpl implements Inter{}//方法一:直接抽象 public class InterImpl implements Inter{ @Override //方法二:实现父接口的抽象方法 public void eat() { System.out.println("吃粽子"); } @Override //实现父接口的抽象方法 public void play() { System.out.println("划龙舟"); } }
3.创建接口测试类
package cn.tedu.inter; /*本类用于测试接口的实现类*/ public class InterTests { //创建程序的入口函数 public static void main(String[] args) { // Inter i = new Inter();//接口不可以创建对象 Inter inter = new InterImpl();//创建多态对象测试 inter.eat(); inter.play(); InterImpl inter1 = new InterImpl();//创建子类对象进行测试 inter1.eat(); inter1.play(); } }
接口之构造方法
package cn.tedu.inter2; /*本类用于进一步测试接口的使用*/ public class TestUserInter { public static void main(String[] args) { Inter2 inter2 = new Inter2Impl();// inter2.eat(); } } /*1.创建接口*/ interface Inter2{ //接口中都是抽象方法 // public Inter2(){} //接口中没有构造方法 public abstract void eat();//创建接口的抽象方法 void eat2(); //接口中的方法简写,默认是抽象方法,会自动拼接 } /*如果一个类没有明确指定父类,那么它的父类就是Object顶级父类*/ //class Inter2Impl extends Object implements Inter2{ /*2.创建接口实现类*/ class Inter2Impl implements Inter2{ //3.创建子类的构造方法 public Inter2Impl(){ super();//默认调用Object的无参构造 System.out.println("我是实现类Inter2Impl的构造方法~"); } @Override public void eat(){ //实现父级接口的eat()方法 System.out.println("端午干粽子"); } }结果显示:
我是实现类Inter2Impl的构造方法~
端午干粽子
总结:接口里是没有构造方法的,接口中的方法全是抽象方法,而且可以简写方法,void eat2()
接口之成员变量
注意:接口中没有普通成员变量,有的只是静态常量,当定义int i = 10时;会默认拼接成public static final int i = 10;
package cn.tedu.inter2; /*本类用于进一步测试接口的使用*/ public class TestUserInter { public static void main(String[] args) { Inter2 inter2 = new Inter2Impl(); inter2.eat(); System.out.println(Inter2Impl.age); System.out.println(inter2.age); } } /*1.创建接口*/ interface Inter2{ // public Inter2(){} //接口中没有构造方法 public abstract void eat();//创建接口的抽象方法 /*接口中没有成员变量*/ int age = 22; //必须初始化赋值,是静态常量,实际写法:public static final int age = 22;在接口中可以省略不写,接口里都是静态常量 } /*如果一个类没有明确指定父类,那么它的父类就是Object顶级父类*/ //class Inter2Impl extends Object implements Inter2{ /*2.创建接口实现类*/ class Inter2Impl implements Inter2{ //3.创建子类的构造方法 public Inter2Impl(){ super(); System.out.println("我是实现类Inter2Impl的构造方法~"); } @Override public void eat(){ //重写父级eat()方法 System.out.println("端午干粽子"); } }结果显示:
我是实现类Inter2Impl的构造方法~
端午干粽子
22
22
接口之综合案例
package cn.tedu.design; /*设计老师类,要求:面向接口编程--先天设计的结果(直接预先设计出规则)*/ public class DesignTeacher2 { public static void main(String[] args) { Teacher2 act = new ACTTeacher2(); act.ready(); act.teach(); Teacher2 cgb = new CGBTeacher2(); cgb.ready(); cgb.teach(); // Teacher2 scd = new SCDTeacher2();//抽象类不能被实例化(不能创建对象) } } //1.创建接口,设计形成父级接口--接口体现的是预先定义好的规则 interface Teacher2{//接口里的方法默认都是抽象方法,所以可以简写 void ready(); void teach(); } //2.创建接口实现类 class ACTTeacher2 implements Teacher2{ @Override public void ready() { System.out.println("ACT老师在备课"); } @Override public void teach() { System.out.println("ACT老师在上课"); } } class CGBTeacher2 implements Teacher2{ @Override public void ready() { System.out.println("CGB老师在备课"); } @Override public void teach() { System.out.println("CGB老师在上课"); } } abstract class SCDTeacher2 implements Teacher2{//抽象类 @Override public void ready(){ System.out.println("SCD老师在备课"); } public abstract void teach();//抽象方法 }结果显示:
ACT老师在备课
ACT老师在上课
CGB老师在备课
CGB老师在上课
抽象类与接口区别
面向抽象编程--后天向上抽取形成的结果(先把各类老师需要的属性、方法都老实写出来,然后才发现这些共同的属性和方法,才向上抽取这些共性,形成规则)。
面向接口编程--先天设计的结果(直接预先设计出规则)。
主要区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4.抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5.抽象类中可以包含静态方法,接口中不能包含静态方法
6.抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7.一个类可以实现多个接口,但只能继承一个抽象类。
扩展:
1、接口中可以有非抽象的方法,比如default方法(Java 1.8)。
2、接口中可以有带方法体的方法。(Java 1.8)
3、接口中的方法默认是public的。
本文详细介绍了Java中的抽象类和接口的概念、特点及使用方法。包括抽象类的定义、抽象方法、构造函数和成员测试等内容,同时对比了抽象类与接口的区别。
4349

被折叠的 条评论
为什么被折叠?



