zoukankan      html  css  js  c++  java
  • 抽象类和接口

     1抽象类

      有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。

      分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊情况,就是方法功能声明相同,但方法功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。

      当定义了抽象函数的类也必须被abstract关键字修饰,被abstract关键字修饰的类是抽象类。

    1.1定义

    抽象类定义的格式:

      abstract class 类名 {

      }

    抽象方法定义的格式:

      public abstract 返回值类型 方法名(参数);

     

    抽象类不一定有抽象方法

    抽象方法一定在抽象类中

    例:

    //抽象类,研发部员工
    public abstract class Developer {
    	//抽象方法
    	public abstract void work();
    	
    	//普通方法
    	public void speak(){
    		System.out.println("研发部员工开会");
    	}
    }
    
    public class JavaEE extends Developer{
    	public void work(){
    		System.out.println("JavaEE工程师正在写JavaEE代码");
    	};
    }
    

      

    public class Test {
    	public static void main(String[] args) {
    		JavaEE javaee=new JavaEE();
    		javaee.work();
    		javaee.speak();
    	}
    }
    

    抽象类前面的小图标是这样的:带一个“A”

     

    1.2抽象类的特点

    1)抽象类和抽象方法都需要被abstract修饰。抽象方法一定要定义在抽象类中,抽象方法没有方法体。

    2)抽象类不可以直接创建对象(抽象类不能new对象),原因:调用抽象方法没有意义。

    3)只有覆盖了抽象类中所有的抽象方法后,就是要把父类所有方法都重写,子类才可以创建对象。只重写部分方法,该子类还是一个抽象类。抽象类中可以写普通方法。

    所以子类如果只重写部分方法,会报错,解决办法是,把所有方法重写,或者子类也定义成抽象类。

    4)抽象类一定是个父类,因为是不断抽取而来的。

    5)抽象类中可以不定义抽象方法。那这个抽象类的存在的意义是:不让该类创建对象,方法可以直接让子类去使用

    6)抽象关键字abstract不可以和以下关键字共存:

      private:私有的方法子类是无法继承到的,也不存在覆盖,而abstract和private一起使用修饰方法,abstract既要子类去实现这个方法,而private修饰子类根本无法得到父类这个方法。互相矛盾。

      final,后面学

      static,后面学 

    之所以继承抽象类,更多的是在思想,是面对共性类型操作会更简单。

     

    1.3练习

     

    public abstract class Staff {
    	private String number;
    	private String name;	
    	
    	public String getNumber() {
    		return number;
    	}
    	public void setNumber(String number) {
    		this.number = number;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	
    	//工作
    	public void work(){
    		System.out.print("员工号为"+number+"的"+name+"员工");
    	}		
    }
    
    public abstract class Developer extends Staff {	
    
    }
    
    public class JavaEE extends Developer{	
    	public void work(){
    		super.work();
    		System.out.println("正在研发淘宝网站");
    	};	
    }
    
    public class Android extends Developer{
    	public void work(){
    		super.work();
    		System.out.println("正在研发淘宝手机客户端软件");
    	};	
    }
    
    public abstract class Maintainer extends Staff{
    	
    }
    
    public class Network extends Maintainer{	
    	public void work(){
    		super.work();
    		System.out.println("正在检查网络是否畅通");
    	};
    }
    
    public class Hardware extends Maintainer{
    	public void work(){
    		super.work();
    		System.out.println("正在修复打印机");
    	};			
    }
    
    public class Test {
    	public static void main(String[] args) {
    		JavaEE j=new JavaEE();
    		j.setName("张春");
    		j.setNumber("111111");				
    		j.work();
    		
    		Android a=new Android();
    		a.setName("王夏");
    		a.setNumber("222222");
    		a.work();
    		
    		Network n=new Network();
    		n.setName("李秋");
    		n.setNumber("333333");
    		n.work();
    		
    		Hardware h=new Hardware();
    		h.setName("赵冬");
    		h.setNumber("444444");
    		h.work();
    	}
    }
    

    2接口

    接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”。

    接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成。这样将功能的定义与实现分离,优化了程序设计。

    一切事物均有功能,即一切事物均有接口。

    举例:如果是人,那么都会吃饭,走路等。但不是所有人都会打球,游泳等。

    举例:笔记本电脑留了usb接口,插鼠标和键盘等。

    所以接口是额外功能的集合,接口只有抽象方法,没有普通方法。

    2.1接口的定义

    声明时使用interface关键字,

    定义接口的文件仍为.java文件,

    编译后仍然会产生.class文件。

    所以接口可以看做是一种只包含了功能声明的特殊类

    定义格式:

      public interface 接口名 {

        抽象方法1;

        抽象方法2;

        抽象方法3;

      }

     

    2.2类实现接口

    类与接口的关系为实现关系,即类实现接口。实现的动作类似继承,只是关键字不同,实现使用implements。

    其他类(实现类)实现接口后,就相当于声明:”我应该具备这个接口中的功能”。实现类仍然需要重写方法以实现具体的功能。

    格式:

      class 类 implements 接口 {

        重写接口中方法

      }

    例:

    public interface Play {	
    	//接口中的成员方法
    	public abstract void play();
    }
    
    public class Student implements Play{	
    	public void play() {
    		System.out.println("学生学会打球");		
    	}	
    }
    
    public class Test {
    	public static void main(String[] args) {
    		Student s=new Student();
    		s.play();	
    	}
    }
    

    接口文件的小图标是这样的:带一个“I”

     

    在类实现接口后,该类就会将接口中的抽象方法继承过来,此时该类需要重写该抽象方法,完成具体的逻辑。

    接口中定义功能,当需要具有该功能时,可以让类实现该接口,只声明了应该具备该方法,是功能的声明。

    在具体实现类中重写方法,实现功能,是方法的具体实现。

    于是,通过以上两个动作将功能的声明与实现便分开了。

    类是现实事物的描述,接口是功能的集合

    2.3接口中成员的特点

    2.3.1成员变量的特点

    接口中定义的变量必须有固定的修饰符修饰:public static final。

    所以接口中的变量也称为常量,其值不能改变。

      public:公共的,权限修饰符,无论在哪里都可以访问被该修饰符修饰的成员

      static:静态,可以直接被类名调用,即类名.变量名(或类名.方法名)

      final:最终的,被final修饰的变量称为常量,一旦赋值不可改变

    例如:Math.PI

    在接口中不加public static final这些的成员变量,也是常量,刚开始用,最好全写上

    例:

    public interface Play {
    	//接口中的成员变量定义
    	public static final String ball="球";	
    }
    
    public class Test {
    	public static void main(String[] args) {		
    		System.out.println(Play.ball);			
    	}
    }
    

     

    这里的常量ball可以直接被类调用,Play.ball

    而且不能更改:

    2.3.2成员方法的特点

    1)接口中可以定义方法,方法也有固定的修饰符,public abstract,不写这两个修饰符也是抽象方法,

    2)不能加方法体

    Tips:

    1)使用interface代替了原来的class,其他步骤与定义类相同

    2)接口中的方法均为公共访问的抽象方法

    3)接口中无法定义普通的成员变量

    4)接口不可以创建对象。

    5)子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。否则子类是一个抽象类。

    创建实现类后,会出现提示,点击add...会自动出现所有需要重写的方法

    2.4接口的多实现

    接口最重要的体现:解决多继承的弊端。将多继承这种机制在java中通过多实现完成了。

    例:

    public interface Fu1 {
    	public abstract int show1();
    }
    
    public interface Fu2 {
    	public abstract void show2();
    }
    
    public class Zi implements Fu1,Fu2{	
    	public int show1() {
    		System.out.println("这是方法1");
    		return 1;
    	}
    	public void show2() {
    		System.out.println("这是方法2");		
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {
    		Zi z=new Zi();
    		z.show1();
    		z.show2();
    	}
    }
    

    如果是这样:

     

    两个接口的方法完全相同,是可以的,因为接口中的方法没有方法体。

    但是,如果是这样:

     

     

    两个接口的方法名相同,但返回值不同,就会报错

     

    这是需要程序员自己避免的

    2.5接口解决多继承的弊端

    弊端:多继承时,当多个父类中有相同功能时,子类调用会产生不确定性(原因在于多继承父类中功能有主体,而导致调用运行时,不确定运行哪个主体内容。)

    而接口中的功能都没有方法体,都是由子类来明确的,就解决了这个弊端。

    2.6类继承类同时实现接口 

    当一个类已经继承了一个父类,它又需要扩展额外的功能,这时接口就派上用场了。

    子类通过继承父类扩展功能,通过继承扩展的功能都是子类应该具备的基础功能。

    如果子类想要继续扩展其他类中的功能,这时通过实现接口来完成。

    接口的出现避免了单继承的局限性。

    父类中定义事物的基本功能。接口中定义事物的扩展功能。 

    :

    public abstract class Dog {
    	public abstract void eat();
    	public abstract void speak();
    }
    
    public interface Drug {
    	public abstract void catchDrug();
    }
    
    public class DrugDog extends Dog implements Drug {
    	public void catchDrug() {		
    		System.out.println("捕获毒品");
    	}	
    	public void eat() {
    		System.out.println("规矩吃饭");		
    	}
    	public void speak() {
    		System.out.println("不叫");		
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {
    		DrugDog d=new DrugDog();
    		d.catchDrug();
    		d.speak();
    		d.eat();
    	}
    }
    

    2.7接口的多继承

    类与类:继承的关系

    接口和类:实现的关系(接口与类不支持多继承,支持多实现)

    接口与接口:也可以使用extends进行继承

    interface Fu1{
    	void show();
    }
    
    interface Fu2{
    	void show1();
    }
    
    interface Fu3{
    	void show2();
    }
    
    interface Zi extends Fu1,Fu2,Fu3{
    	void show3();
    }

    2.8接口思想在开发中的好处

    1)接口的出现扩展了功能。

    2)接口其实就是暴漏出来的规则。

    3)接口的出现降低了耦合性,即设备与设备之间实现了解耦。

    4)接口的出现方便后期使用和维护。

    举例:电脑上留有很多个插口,而这些插口可以插入相应的设备,这些设备在生产的时候符合了这个插口的使用规则,否则将无法插入接口中,更无法使用。这个插口的出现让我们使用更多的设备。

    2.9接口和抽象的区别

    相同点:

    1)都位于继承的顶端,用于被其他类实现或继承;

    2)都不能直接实例化对象;

    3)都可以包含抽象方法,其子类都必须覆写这些抽象方法;

     

    区别:

    1)抽象类为部分方法提供实现,避免子类重复实现这些方法,提高代码重用性;

      接口只能包含抽象方法;

    2)一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承)

    3)抽象类是这个事物中应该具备的内容, 继承体系是一种 is..a(是一个)关系

          接口是这个事物中的额外内容,继承体系是一种 like..a(会什么功能)关系

     

    总结: 

    优先选用接口,尽量少用抽象类;

    需要定义子类的行为,又要为子类提供共性功能时才选用抽象类。

     

  • 相关阅读:
    Qt计算器开发(三):执行效果及项目总结
    [HNOI2019]校园旅行
    How to fix nuget Unrecognized license type MIT when pack
    How to fix nuget Unrecognized license type MIT when pack
    git 通过 SublimeMerge 处理冲突
    git 通过 SublimeMerge 处理冲突
    git 上传当前分支
    git 上传当前分支
    gif 格式
    gif 格式
  • 原文地址:https://www.cnblogs.com/hzhjxx/p/10054175.html
Copyright © 2011-2022 走看看