Java基础--继承、抽象、接口

来源:互联网 发布:linux如何解压zip文件 编辑:程序博客网 时间:2024/04/29 17:29


一、继承

    1.概念

         把很多类的相同特征和行为进行抽取,用一个类来描述。让多个类和这个类产生一个关系。这样,多个类就可以省略很多代码。这个关系就是继承。java中用extends关键字表示。

    2.继承的特点

         1):java中只能单继承,没有多继承。

         2):java可以有多重(层)继承。

    3.继承的体系结构

        1):概念:多个具体的对象,不断的向上抽取共享的内容,最终形成了一个体系。这个体系叫做继承体系。

        2):继承体系的学习和使用原则:

              a)学习顶层的内容。因为他是整个体系的共性内容。

              b)创建子类使用。也就是使用底层的具体对象。

    4.继承的好处:

         1)继承的出现提高了代码的复用性。

         2)继承的出现让类与类之间产生了关系,提供了多态的前提。

    5.子父类中的成员关系

       A:成员变量

           在子类方法中使用一个变量时:

           首先,在方法的局部变量中找这个变量,有则使用。

           否则,在本类中找成员变量,有则使用。

           否则,在父类中找成员变量,有则使用。

           否则,报错。

       B:成员方法

           用子类对象使用一个方法时。

           首先,在子类中找这个方法,有则使用。

           否则,在父类中找这个方法,有则使用。

           否则,报错。

    6.重写和重载的区别?

        重载:在同一类中。方法名相同,参数列表不同。重载可以改变返回类型。

        重写:在不同类中(子父类中)。方法声明相同(返回类型,方法名,参数列表均相同)。

        重写需要注意:

           1)子类方法的访问权限要大于等于父类方法的访问权限。

           2)静态只能重写静态。但是这种情况一般不会出现。

     7.this和super的区别

          this:代表本类对象的引用。

          super:代表父类的存储空间。

     8.final关键字(重点)

        1)最终的意思,可以用于修饰类,方法,变量。

        2)final修饰的类不能被继承。

        3) final修饰的方法不能被重写。

        4) final修饰的变量是一个常量。只能被赋值一次。

        5)内部类只能访问被final修饰的局部变量。

     程序示例:   

<span style="font-size:14px;">class Person{ //定义一个父类PersonString name;int age;Person(String name,int age){this.name =name;this.age=age;System.out.println("姓名: "+name+" 年龄: "+age);}//Person共有功能eatpublic void eat(){   System.out.println("eat");}}class Student extends Person{   //定义一个子类student继承PersonStudent(String name,int age){super(name,age); //super关键字表示父类,因为姓名和年龄在父类中进行了初始化动作,在这里可以直接调用  } //Student特有功能studyvoid study(){  System.out.println("study");}//Student特有功能examvoid exam(){System.out.println("exam");}}public class PersonExtends1 {public static void main(String[] args) {     Student stu=new Student("qiao",23);     stu.eat();     stu.study();     stu.exam();}}</span>

  二、抽象类  

1.概念

        抽象就是从多个事物中将共性的,本质的内容抽取出来。

    2.特点

       1):抽象类和抽象方法都要用abstract进行修饰

       2):抽象类不能被实例化

       3):抽象类中不一定有抽象方法,但是,有抽象方法的类一定是抽象类。

    3.抽象类中数据的特点

       A:成员变量

            抽象类中可以有变量,也可以有常量。

       B:成员方法

            抽象类中可以有抽象方法,也可以有非抽象方法。

       C:构造方法

            抽象类是一个类,所以,它有构造方法。 虽然本身不能实例化。但是可以给子类实例化使用。

    4.抽象类中的问题

        1):抽象类中是否有构造方法?能不能被实例化?如果不能,为什么有构造方法?

               抽象类有构造方法。 抽象类不能被实例化。抽象类中的构造方法供子类实例化调用。

        2):抽象关键字abstract不可以和哪些关键字共存?

               a):private,私有内容子类继承不到,所以,不能重写。但是abstract修饰的方法,要求被重写。两者冲突。

               b):final,final修饰的方法不能被重写。而abstract修饰的方法,要求被重写。两者冲突。

               c):static假如一个抽象方法能通过static修饰,那么这个方法,就可以直接通过类名调用。而抽象方法是没有方法体的,这样的调用无意义。

        3):抽象类中可不可以没有抽象方法?如果可以,这样的类有什么用吗?

               抽象类可以没有抽象方法。抽象类中没有抽象方法的作用,只是为了不让别的类建立该抽象类对象。

      程序示例:

<span style="font-size:14px;">abstract class Person{//定义抽象方法run()abstract void run();}class Student extends Person{//实现抽象方法run()void run(){System.out.println("Run");}}public class Abstract1 {public static void main(String[] args) {     Student stu=new Student();//创建Student实例对象     stu.run();//调用Student的run()方法}}</span>

三、接口

    1.概念

        当一个类中的方法都是抽象的时候,java提供了另一种表示方式,叫接口。

       用interface关键字表示。类与接口关系用implements表示。

    2.接口的成员特点

        A:成员变量

             是常量,默认修饰 public static final

        B:成员方法

             都是抽象的,默认修饰 public abstract

    3.关系
       A:类与类的关系

            是继承关系。类与类只能单继承,可以多重继承。

       B:类和接口的关系

           是实现关系。类在继承一个类的同时,可以多实现接口。

       C:接口和接口的关系

           是继承关系。接口可以多继承接口。

    4.接口的特点

         1):是对外暴露的规则

         2):是功能的扩展

         3):接口的出现降低耦合性。(耦合:类与类之间的关系、内聚:类完成功能的能力)

             编程规范:低耦合,高内聚。

         4):接口可以多实现。如:CPU和主板、笔记本的USB插口、插座

   

 四.抽象类和接口的区别

       

1.语法层面上的区别

  1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

  2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

  3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

  4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

2.设计层面上的区别

  1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。


     此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比

战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关

系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比

如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。


  2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简

单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只

需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更

新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了

变更,则所有实现这个接口的类都必须进行相应的改动。


  下面看一个网上流传最广泛的例子:门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口

来定义这个抽象概念:

            

<span style="font-size:14px;">abstract class Door {    public abstract void open();    public abstract void close();}</span>

    但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:

  1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能;

  2)将这三个功能都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )

这两个功能,比如火灾报警器。

     从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而

alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close

种行为。再设计一个报警门继承Door类和实现Alarm接口。


<span style="font-size:14px;">interface Alram {    void alarm();} abstract class Door {    void open();    void close();} class AlarmDoor extends Door implements Alarm {    void oepn() {      //....    }    void close() {      //....    }    void alarm() {      //....    }}</span>




1 0