您的位置:首页 > 编程语言 > Java开发

[2014-3-11]JAVA笔记_抽象类(abstract class)、接口(interface)

2014-03-11 16:26 645 查看
一、 抽象类

抽象类(abstract class):使用abstract 关键字所修饰的类叫做抽象类。抽象类无法实例化,也就是说,不能 new 出来一个抽象类的对象(实例)。

抽象方法(abstract method):使用abstract 关键字所修饰的方法叫做抽象方法。抽象方法定义在抽象类中。抽象方法只有声明,没有实现,也就是说没有{}。

         ·如果某个类是抽象类,那么该类可以包含具体方法(有声明、有实现)。

         ·如果一个类中包含了抽象方法,那么这类一定要声明成abstract class ,也就是说,该类一定是抽象类;反之,如果某个类是抽象类,那么该类即可以包含抽象方法,也可以包含具体方法(全部是具体方法也可),也可以没有方法。

         ·无论何种情况,只要一个类是抽象类,那么这个类就无法实例化。

·在子类继承父类(父类是个抽象类)的情况下,那么该子类必须要实现父类中所定义的所有抽象方法;否则,该子类需要声明成一个 abstract class。

注意:不能直接由抽象类创建对象,只能通过抽象类派生出新的类,再由它来创建对象。同样存在单继承的局限,即一个子类只能继承一个抽象类。

//继承抽象类
abstract class A{			//包含抽象方法所以必须定义为抽象类
public static final String FLAG = "CHINA";
private String name = "Jerry";
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public abstract void print();   //定义抽象方法。只需要声明,不需要实现。

}
//抽象类必须被子继承才可用抽象类
class B extends A{
//因为子类不是抽象类,所以必须覆写抽象类中的全部抽象方法
public void print(){
System.out.println("FLAG = " + FLAG);
System.out.println("姓名 = " + super.getName());
}
}
public class AbstractDemo02{
public static void main(String args[]){
B b = new B();
b.print();
}
}
注意:·

. 抽象类不能用final关键字定义。因为抽象类必须被继承,而使用final关键字定义的类不能被继承。

·. 抽象方法不要使用private声明。因为抽象方法必须被子类覆写,而如果使用private声明则子类无法覆写。

2. 抽象类中可以存在构造方法

//调用抽象类中指定参数的构造方法
abstract class Person{
private String name;
private int age;
public Person(String name, int age){
this.setName(name);
this.setAge(age);
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public abstract String getInfo();		//取得信息,抽象方法

}
class Student extends Person{
private String school;
public Student(String name, int age, String school){
super(name, age);
this.setSchool(school);
}
public String getSchool(){
return school;
}
public void setSchool(String school){
this.school = school;
}
public String getInfo(){			//覆写抽象类中的抽象方法
return 	"姓名:" + super.getName() +
";年龄:" + super.getAge() +
";学校:" + this.getSchool();
}
}
public class AbstractDemo03{
public static void main(String args[]){
Student stu = new Student("张三", 30, "清华大学");
System.out.println(stu.getInfo());
}
}
总结:抽象类就是比普通类多定义了一个抽象方法,除了不能直接进行对象的实例化操作之外并没有任何的不同。

二、接口

接口(Interface):接口的地位等同于class, 接口中的所有方法都是抽象方法。在声明接口中的方法时,可以使用 abstract 关键字,也可以不用。通常情况会省略 abstract 关键字。

概念:可以将接口看作是特殊的抽象类(抽象类中可以有具体方法,也可以有抽象方法,而接口中只能有抽象方法,不能有具体方法)。接口是由全局常量或公共的抽象方法所组成。

·类可以实现接口。实现使用关键字 implements 表示,代表了某个类实现了某个接口。

· 一个类实现了某个接口,那么该类必须要实现接口中声明的所有抽象方法。如果该类是抽象类,那么就无需实现接口中的方法了(也可以实现,不过没意义,因为抽象类不能被实例化)。

·Java 是单继承的,也即是说某个类只能有唯一一个父类;一个类可以实现多个接口,多个接口之间使用逗号分隔。

·接口可以继承接口(interface A extends B, C),接口不能实现接口(interface A implements B, C),类可以实现接口,但类不能继承接口(class A extends B, C)。(例如类是具体要做什么是实体的,而接口是抽象的、无实现的。所以抽象的可以继承抽象的,抽象的不能实现抽象的,实体的可以实现抽象的,实体的不能继承抽象的,因为实体的是告诉我们这个类具体是做什么的,而不是告诉我们他是什么)

 ·接口继承接口后接口的方法也被继承下来,可以通过子类实现子接口,子类重写子接口方法和父接口方法。

why?:不允许类多重继承的主要原因是,如果A同时继承B和C,而b和c同时有一个D方法,A如何决定该继承那一个呢?但接口不存在这样的问题,接口全都是抽象方法继承谁都无所谓,所以接口可以继承多个接口。因为类如果可以多继承,实例化时,如果要跳用父类的方法,如果两个一样,根本就不知道该调用那个父类的方法;但是接口就不一样了,因为接口继承多个接口,就算多个接口有相同的方法,但是最终实现接口的类只能实现一个方法且@Override一个方法,所以调用时就不会有问题了。
 

范例:接口中的方法必须全部实现。可以选择由抽象类实现一部分,子类实现另一部分,或者其同包里面的其他类实现。

package com.bob.test;

public class InterfaceTest {
public static void main(String[] args) {
C c = new C();
c.print1();
}

}

interface A{
public abstract void print1();
public abstract void print2();
public abstract void print3();
}
//抽象类可以选择性实现抽象方法,但是未实现的抽象方法必须由子类实现,或者同包下的其它类文件实现
abstract class B implements A{
public void print1(){
System.out.println("AAA");
}
}
另一个类文件
package com.bob.test;

public class AbstractMethodTest {

}
class C extends B{
public void print2(){
System.out.println("BBB");
}
public void print3(){
System.out.println("CCC");
}
}


[接口的定义格式]

interface 接口名称{

全局常量;

抽象方法;

}

注:java中接口的访问权限默认是public,不管写与不写,接口中的方法永远是public。

//在接口中使用多态
public class Test4{
public static void main(String args[]){
AA aa = new BB();	//aa类型的引用指向bb类型的对象
aa.output();
//BB bb = (BB)aa;	//向下类型转换,与类转换方法相同
}
}

interface AA{
public abstract void output();
}
class BB implements AA{
public void output(){
System.out.println("BB");
}
}


多态总结:所谓多态,就是父类型的引用可以指向子类型的对象,或者接口类型的引用可以指向实现该接口的类的实例。关于接口与实现接口的类之间的强制类型转换方式与父类和子类之间的强制类型转换方式完全一样。

[格式   实现接口]

class 类 implements 接口A, 接口B,...{

}

//接口的实现
interface A{					//默认public权限,可省略
public String AUTHOR = "Jerry";			//定义全局常量,省略写法
//	public staitc final String AUTHOR = "Jerry";	//定义全局常量,完整写法
public void print();				//定义抽象方法,省略写法
public abstract String getInfo();	//定义抽象方法,完整写法
}
interface B{				//定义接口B
public abstract void say();			//定义抽象方法
}
class X implements A,B{			//子类同时实现两个接口
public void say(){			//覆写B接口中的抽象方法
System.out.println("Hello Interface");
}
public String getInfo(){		//覆写A接口中的抽象方法
return "HELLO";
}
public void print(){			//覆写A接口中的抽象方法
System.out.println("作者:" + AUTHOR);
}
}
public class InterfaceDemo03{
public static void main(String args[]){
X x = new X();			//实例化子类对象
x.say();				//调用被覆写过的方法
x.print();				//调用被覆写过的方法
}
}


子类既要实现接口又要继承抽象类

//子类同时继承抽象类和实现接口
interface A{					//默认public权限,可省略
public String AUTHOR = "Jerry";			//定义全局常量,省略写法
//	public staitc final String AUTHOR = "Jerry";	//定义全局常量,完整写法
public void print();				//定义抽象方法,省略写法
public abstract String getInfo();	//定义抽象方法,完整写法
}
abstract class B{				//定义抽象类B
public abstract void say();			//定义抽象方法
}
class X extends B implements A{			//子类同时实现接口
public void say(){			//覆写B接口中的抽象方法
System.out.println("Hello Interface");
}
public String getInfo(){		//覆写A接口中的抽象方法
return "HELLO";
}
public void print(){			//覆写A接口中的抽象方法
System.out.println("作者:" + AUTHOR);
}
}
public class InterfaceDemo04{
public static void main(String args[]){
X x = new X();			//实例化子类对象
x.say();				//调用被覆写过的方法
x.print();				//调用被覆写过的方法
}
}


抽象类实现接口

//子类同时继承抽象类和实现接口
interface A{					//默认public权限,可省略
public String AUTHOR = "Jerry";			//定义全局常量,省略写法
//	public staitc final String AUTHOR = "Jerry";	//定义全局常量,完整写法
public void print();				//定义抽象方法,省略写法
public abstract String getInfo();	//定义抽象方法,完整写法
}
abstract class B implements A{				//定义抽象类,实现接口
public abstract void say();			//此时抽象类中存在3个抽象方法
}
class X extends B {				//子类继承抽象类
public void say(){			//覆写抽象B接口中的抽象方法
System.out.println("Hello Interface");
}
public String getInfo(){		//覆写抽象类B中的抽象方法
return "HELLO";
}
public void print(){			//覆写象类B中的抽象方法
System.out.println("作者:" + AUTHOR);
}
}
public class InterfaceDemo05{
public static void main(String args[]){
X x = new X();			//实例化子类对象
x.say();				//调用被覆写过的方法
x.print();				//调用被覆写过的方法
}
}


java中一个接口是不允许继承抽象类的,但是允许一个接口继承多个接口

[格式 接口的继承]

interface 子接口 extends 父接口A, 父接口B,...{

}

//接口的多继承
interface A{					//默认public权限,可省略
public String AUTHOR = "Jerry";			//定义全局常量,省略写法
//	public staitc final String AUTHOR = "Jerry";	//定义全局常量,完整写法
public abstract void printA();				//定义抽象方法,省略写法
}
interface B{
public abstract void printB();		//定义抽象方法
}
interface C extends A,B{			//定义接口C, 同时继承接口A、B
public abstract void printC();
}
class X implements C{				//子类实现接口C
public void printA(){
System.out.println("A、Hello World");
}
public void printB(){				//覆写接口B中的printB()方法
System.out.println("B、Hello SDD");
}
public void printC(){
System.out.println("C、Hello DD");		//覆写接口B中的printB()方法
}
}
public class InterfaceDemo06{
public static void main(String args[]){
X x = new X();
x.printA();
x.printB();
x.printB();
}
}//子接口继承父接口,那么实现子接口的时候必须覆写子、父接口中所有的抽象方法

接口:由全局常量和抽象方法组成,默认是public权限,同抽象类相同也是由子类实现。因为接口中的方法默认是抽象方法,所以子类实现接口时必须覆写所有接口中的方法。

抽象类:由abstract关键字定义的方法是抽象方法,包含一个抽象方法的类是抽象类,默认是public权限。抽象方法只需要申明,不需要实现,也就是没有{}主体内容。抽象类如果要使用必须由子类继承,而且子类必须覆写所有定义为abstract的抽象方法。

·如果一个抽象类实现了接口中一部分方法,另一个类继承自抽象类,那么子类必须实现抽象类中未实现的抽象方法
package com.bob.annotation;

public interface Usb {

public abstract void methoud1();
public abstract void methoud2();

public abstract void methoud3();
public abstract void methoud4();
}

//实现接口中的部分方法
abstract class Print implements Usb{
@Override
public void methoud1() {
System.out.println("implments method1.");

}
@Override
public void methoud2() {
System.out.println("implments method2.");

}

}
package com.bob.annotation;

//继承抽象类Print
class Test extends Print {
public static void main(String[] args) {
Test test1 = new Test();
test1.methoud1();

}

//实现抽象类中未实现的方法
@Override
public void methoud3() {}

@Override
public void methoud4() {}

}
·如果一个抽象类实现了接口中的所有方法,方法体为空,那么子类继承抽象类可以选择性的实现自己需要的方法。或者重写父类中的方法
package com.bob.annotation;

public interface Usb {

public abstract void methoud1();
public abstract void methoud2();

public abstract void methoud3();
public abstract void methoud4();
}

//实现接口全部方法
abstract class Print implements Usb{
@Override
public void methoud1() {      //子类只想使用接口中的一个方法,可以用抽象类实现
System.out.println("implments method1.");

}
@Override
public void methoud2() {}

@Override
public void methoud3() {
// 空实现

}@Override
public void methoud4() {
// 空实现

}

}

package com.bob.annotation;

//继承抽象类Print
class Test extends Print {
public static void main(String[] args) {
Test test1 = new Test();
test1.methoud1();

test1.methoud2();

}
@Override
public void methoud2() {
System.out.println("重写父类的method2方法");
}
}·抽象类肯定可以实现接口。这不是有没有意义的事情,是一种思想,当你自己写的类想用接口中个别方法的时候(注意不是所有的方法),那么你就可以用一个抽象类先实现这个接口(方法体中为空),然后再用你的类继承这个抽象类,这样就可以达到你的目的了,如果你直接用类实现接口,那是所有方法都必须实现的; 
·这种思想在java.swing.event包中运用的非常多,里面一般以Adapter为后缀的都是抽象类,它们都实现了特定的事件接口,大家可以看看。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: