抽象类与抽象方法总结、接口定义与实现过程、抽象类与接口的比较

抽象类概念:

用关键字 abstract 修饰的类就是抽象类(abstract 类);

如:public abstract class A{ ... }

1、抽象类中可以有抽象方法,也可以没有抽象方法;

2、抽象类中可以有非抽象方法,如 实例方法,static 方法,final 方法 ;

3、子类继承抽象类,则需要重写抽象类中全部的抽象方法;(重写时,去掉关键字 abstract,加上方法体{ } )

4、子类继承抽象类,可以决定是否重写抽象类中非抽象方法;(没有重写的非抽象方法,则被子类继承)

5、抽象类不能实例化对象,则不能通过 new运算符 创建对象;

6、抽象类可以通过子类创建上转型对象;

如下代码↗:

//抽象类
public abstract class Animal {
	//抽象方法,动物的叫声
	abstract void cry();
	//抽象方法,动物的名字
	abstract void getAnimalName();
	void method(){
		System.out.println("我是抽象类中非抽象方法,被子类继承或者重写");
	}
}
//子类继承抽象类
public class Cat extends Animal{
        //重写抽象类中抽象方法
	void cry() {
	   System.out.println("喵喵瞄~~~");
	}
	void getAnimalName() {
		System.out.println("猫");
	}
	//重写抽象类中非抽象方法
        void method(){
	   System.out.println("重写了抽象类中非抽象方法");
	}

 public static void main(String[] args){
	   //创建子类对象
	   Cat cats = new Cat();
	   System.out.println("子类对象cats的引用:"+cats);
	   //创建子类上转型对象
	   Animal ani;
	   ani = cats;
	   System.out.println("上转型对象ani的引用:"+ani);   
   }
}

代码输出结果:

子类对象cats的引用:Chapter_FiveTwo.Cat@7852e922
上转型对象ani的引用:Chapter_FiveTwo.Cat@7852e922

需要注意的是:

抽象类的子类也可以是抽象类,这种情况下,子类可以不 重写抽象类的抽象方法,而是选择 继承抽象方法;

如下代码↗:

//抽象类
public abstract class Animal {

	//抽象方法,动物的叫声
	abstract  void cry();
	//抽象方法,动物的名字
	abstract void getAnimalName();
	
	void method(){
		System.out.println("我是抽象类中非抽象方法,被子类继承或者重写");
	}
	
}
//抽象类继承抽象类
public abstract class Cat extends Animal{
        //可以选择 重写抽象类中抽象方法,也可以选择 继承抽象方法
	void cry() {
	   System.out.println("喵喵瞄~~~");
	}

	//重写抽象类中非抽象方法
        void method(){
	   System.out.println("重写了抽象类中非抽象方法");
	}

}

代码中,抽象类 Cat 继承了 抽象类 Animal,选择重写了 抽象方法 cry() , 继承了 抽象方法 getAnimalName() ;


抽象方法概念:

用关键字 abstract 修饰的方法就是抽象方法(abstract 方法);

如: abstract void method();

1、抽象方法没有方法体{};

2、抽象方法不能和 static 关键字一起使用;如:abstract static void method();  //是错误的

3、抽象方法不能和 final 关键字一起使用;如:abstract final void method();  //是错误的


接口的定义:

用关键字 interface 来定义一个接口;

如:public interface Printable{ }  //public 访问权限的接口

       interface Printable{ }  //友好 访问权限的接口

1、JDK1.7以及以下JDK版本中,接口体只有常量的声明和抽象方法两部分;

2、JDK1.8以及以上JDK版本中,接口体还可以声明 static 方法 ;

3、接口体中所有常量的访问权限都是 public ,而且是 static 常量;

如:public static final double variable = 11.11 ;

(允许省略 public static final 不写,如:double variable = 11.11 ; ) 

4、接口体中所有抽象方法的访问权限都是 public ;

如:public abstract void method() ;

(允许省略 public abstract 不写,如:void method() ; ) 

5、接口体中的 static 方法,只能通过类名进行调用,接口变量 和 实现类创建的对象 都不能进行调用接口的 static 方法;


接口的实现:

接口需要使用关键字 implements 来实现;

如:public class A implements InterfaceFa { }     //类A实现了接口InterfaceFa

1、一个类(抽象类,非抽象类),可以通过 implements 实现多个接口;

如:public class A implements InterfaceFa , InterfaceCh { }    //怎么非抽象类A就要重写这两个接口的全部抽象方法

2、一个非抽象类,实现了某个接口,那么这个类必须要重写这个接口中全部抽象方法;

如:public class A implements InterfaceFa { }    //怎么非抽象类A就要重写接口 InterfaceFa 的全部抽象方法

3、一个抽象类,实现了某个接口,那么这个抽象类就可以重写接口中的方法,也可以直接拥有接口中的方法;

如:public abstract class A implements InterfaceFa { } 

4、一个接口可以通过 extends 继承另外一个接口,或者多个接口,那么这个接口就拥有了所继承接口的全部抽象方法和常量;

如:public interface A extends InterfaceFa , InterfaceCh { } 

5、对于接口中的常量,可以在实现类中直接调用,也可以通过 接口名 . 常数名、接口变量 . 常数名 进行调用 ;

如下代码↗:

                //接口变量操作接口中的常数
		System.out.println("接口变量操作接口中常数"+ifa.valiablesFa);
		//接口名操作接口中的常数
		System.out.println("接口名操作接口中的常数"+interfaceFa.valiablesFa);
		//实现类中直接操作接口中的常数
		System.out.println("实现类中直接操作接口中的常数"+(valiablesFa+12));

6、如果一个类的父类实现了某个接口,那么这个类也默认地实现了这个接口;


接口回调、接口变量的实现:

接口属于引用型变量,接口变量中可以存放类的对象引用,通过接口变量就可以实现接口回调;

简单的说:将类对象的引用赋值给接口变量后,该接口变量就可以回调类重写的接口方法;

如下代码↗:

public class interfaceCh implements interfaceFa {
	 //创建接口变量
	 static interfaceFa ifa ;
         //重写接口抽象方法
         public void importsFa() {
		System.out.println("importsFa");
	}
	
	public static void main(String[] args){
		
		System.out.println(ifa);  //输出为 NULL
		//进行接口回调,通过接口回调创建的变量,可以调用实现类重写接口的方法
		interfaceCh ich = new interfaceCh();
		ifa = ich ;           //接口变量存放对象的引用
		System.out.println(ich);    //输出的引用一样
		System.out.println(ifa);
                //分别使用 接口变量 和 实现类对象 调用重写方法;
		ifa.importsFa();    //接口回调
		ich.importsFa();
	}
}

代码中 接口变量 ifa 通过接口回调,调用了被实现类重写的接口方法,但是接口变量不能调用 实现类自己原有的方法;


接口与多态:

接口与多态的关系就是:不同的类分别实现一个接口时,这些类通过方法重写,就可以具有不同的实现方式,那么接口变量在回调这些接口方法时就可以具有多种形态了;


接口参数(方法参数类型为接口类型):

接口参数指:一个方法的参数类型是接口类型的,这样就可以将任何实现该接口的类的对象引用传递给该接口参数;

接口参数作用:通过接口参数,可以回调类重写的接口方法了;

如下代码↗:

public class interfaceCh implements interfaceFa {
	
    //重写接口的方法
	public void importsFa() {
		System.out.println("importsFa");
	}
	
    //接口参数,回调实现类重写的接口方法importsFa
    public void methodParameter(interfaceFa itf){
    	itf.importsFa();
    }
	
	public static void main(String[] args){
		//创建实现类对象,进行方法传参
		interfaceCh ich = new interfaceCh();
		ich.methodParameter(ich);
	}
}

抽象类与接口的比较:

相同点:

1、抽象类与接口中 都有抽象方法;

2、抽象类与接口中 都有常量;

3、一般类继承抽象类与实现接口时,都要重写它们中的抽象方法 ;

不同点:

1、抽象类中可以有非抽象方法,接口没有;(除了JDK1.8及以上版本声明的接口)

2、抽象类中可以有变量,接口没有;

3、一般类只能继承一个抽象类,但可以实现多个接口;


需要注意的是:

JDK1.8及以上版本的接口,除了可以声明 static 方法,还可以声明 默认方法 (default 方法);

如下代码↗:
 

public interface inter{
//声明 默认方法 (default 方法) 
default void print(){ 
       System.out.println("我是一辆车!"); 
   } 
}

对于默认方法的使用,总结了下面两点:

一、一个接口继承了另外一个接口,就可以重写继承接口中的默认方法了;

二、一般类实现了某个接口,一般类中的实例方法可以通过  接口名 . super . 默认方法名 ; 进行调用;

void methods( ){
        interfaceFa.super.print();
    }


对于以上定义,我们应该什么时候使用 抽象类,什么时候使用 接口呢?

要根据子类的需求进行考虑,

当子类除了需要重写父类的 抽象方法外,还需要从父类继承一些 非抽象方法时,就可以考虑使用 抽象类了,

当子类不需要继承,只是需要某些重要的 抽象方法的实现细节,就可以考虑使用 接口了 ;

发布了57 篇原创文章 · 获赞 10 · 访问量 7534

猜你喜欢

转载自blog.csdn.net/LagerSwan/article/details/104309740