抽象类
为什么要引入抽象类?
有时候我们在创建父类时由于我们还没有确定我们需要给类中定义那些成员变量、成员方法的具体功能,所以我们没法确定这个类的具体化功能,只是需要声明一下这个方法。所以我们引入抽象类的概念,我们用抽象类在父类中声明抽象方法。
抽象类的特点
抽象类不能直接实例化(不能创建对象!)
如果一个类中有抽象方法,那么这个类一定是抽象类。(抽象类才有抽象方法!)
如果一个类定义为抽象类,那么这个类中不一定都是抽象方法。(抽象类不全是抽象方法!)
当子类也为抽象类时,因为不能创建子类的对象,所以我们认为,创建抽象类的抽象子类是没有什么意义的。(子类必须实现父类的功能!)
关键字:abstract
抽象类的成员特点
成员变量:可以是常量也可以是变量。
构造方法:可以是有参构造,也可以是无参构造,都是对类进行初始化。
成员方法:可以有抽象类成员方法,也可以有非抽象类的。
abstract关键字和哪些关键字冲突?
因为抽象类需要具体的实现,所以与 private、static、final冲突。
接口
为什么要引入接口?
以猫狗案例说明,因为猫狗他们具有后天学习能力,他们可以学习其他的能力(如玩耍),所以我们就引入了接口功能,JAVA接口与电脑的USB接口差不多,都是体现扩展性功能的。所以:接口中只能有抽象方法,不能有方法体!
接口的特点
接口的格式:
interface 接口名{ 抽象方法; 抽象方法; ... }
同我们抽象类,接口也是不可以创建对象的(不能实例化),我们只能用类来“实现”接口的功能,故我们需要谈到接口子类实现化的格式:
格式: class 类名 implements 接口名{} //这里类名我们根据JAVA规范要求的见名知意,类名一般选择在原类名后续上impl
因为接口中都为抽象类,所以作者将方法的 public abstract 这两个确定的关键字直接省略,不用我们敲。
例子:
interface JavaStudy{ public abstract void SE(); public abstract void DataBase(); public abstract void EE(); } class StudentImpl implements JavaStudy{ @Override public void SE() { System.out.println("hello SE"); } @Override public void DataBase() { System.out.println("hello DataBase "); } @Override public void EE() { System.out.println("hello EE"); } } public class TestDemo { public static void main(String[] args) { StudentImpl s = new StudentImpl(); s.SE(); s.DataBase(); s.EE(); }
接口成员的特点
成员变量:是一个常量,不能修改,默认的修饰符为
public static final
(也就确定了前面说的那些特点,区别于抽象类)。
构造方法:接口中没有构造方法。(区别于抽象类)
成员方法:只能是抽象方法,默认省略public abstract。(区别于抽象类)
例子:
interface Interface { public static final int num = 10;//默认就是这样的 int num1=20;//实际中我们可以这样简写,另外,public这个关键字是固定的,用default和private关键字替代都是错的 //由快捷键是无法创建有参构造和无参构造的,嗯,接口中没有构造方法。 void method();//声明一个抽象类,默认省略public abstract } //接口的实现类 class InterfaceImpl implements Interface{ @Override public void method() { System.out.println("这是我复写的method方法"); } } public class TestDemo { public static void main(String[] args) { Interface i = new InterfaceImpl();//接口多态 // i.num = 20 ;//已经报错了,说明了修饰符存在,是final起的作用 // i.num1 = 20 ;//虽然我们没有修饰num1,但是还是提示了相同的错误,说明修饰符默认存在! i.method(); System.out.println(Interface.num1);//说明成员变量是默认static修饰的 System.out.println(InterfaceImpl.num); } }
接口作为形式参数的问题
/** * 实际开发中,接口作为形式参数的问题 * * 如果形式参数是接口: * 传统的方式: 1)提供给接口的子实现类 * 2)内部类的方式(不需要提供子实现类) * @author Administrator * */ interface Inter2{ public abstract void study(); } //具体类 class StudentDemo{ public void method(Inter2 i) {//Inter2 i = new Inter2() ;//错误 i.study(); } } class InterImpl2 implements Inter2{ @Override public void study() { System.out.println("好好学习,天天向上..."); } } //测试类 public class Demo { public static void main(String[] args) { //需求:需要调用StudentDemo这个类中method()方法 StudentDemo sd = new StudentDemo() ; //接口多态的形式 Inter2 i = new InterImpl2() ; sd.method(i); System.out.println("---------------"); //链式编程:匿名对象 new StudentDemo().method(new InterImpl2()); System.out.println("----------------"); Inter2 i2 = new Inter2() { @Override public void study() { System.out.println("好好学习,天天向上..."); } }; i2.study(); } }
拓展
继承给我们提供了子类继承父类的好处,接口给我们提供了扩展性功能的好处,抽象类告诉我们在我们不明确方法功能时的抽象声明。我们可以将这三大功能联合应用起强大来,可以实现强大的功能 (╯‵□′)╯︵┻━┻