java 抽象类 接口 内部类

1.抽象类

1.1 抽象类和抽象方法

      抽象方法定义的格式:

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

      抽象类定义的格式:

      abstract class 类名 {

      }

      抽象类和抽象方法必须使用abstract修饰符来定义,有抽象方法的类必须定义为抽象类,抽象类里可以没有抽象方法。抽象类和抽象方法的规则:

     a.抽象类和抽象方法必须使用abstract来修饰,抽象方法不能有方法体;

     b.抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。即使抽象类里不含抽象方法,这个抽象类也不能创建实例;

     c.抽象类可以包含成员变量方法(普通方法和抽象方法都可以)构造器初始化块 内部类(接口 枚举)五种成分。抽象里不能创建实例,只能当作父类被其他子类继承。抽象类的构造器不能用于创建实例,主要用于被其子类调用;

     d.含抽象方法的类(包括直接定义一个抽象方法;或继承了一个抽象父类,但没有完全实现父类包含的抽象方法;或实现了一个接口,但没有完全实现接口包含的抽象方法)只能被定义成抽象类。

        Abstract不能用于修饰成员变量,不能用于修饰局部变量,即没有抽象变量没有抽象成员变量;abstract也不能用于修饰构造器,没有抽象构造器,抽象类里定义的构造器只能是普通的构造器。当使用abstract修饰类时,表明这个类只能被继承;当时用abstract修饰方法时,表明这个方法必须由子类提供实现(即重写)。Final修饰的类不能被继承,final修饰的方法不能被重写。所以final和abstract永远不能同时使用。Static和abstract不能同时修饰某个方法,可以同时修饰内部类。

1.2 抽象类的作用

        抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个类为其子类的模板,从而避免了子类设计的随意性。抽象类体现的就是模板模式的设计。

2.接口

        抽象类是从多个类中抽象出来的模板,如果将这种抽象进行得更彻底,则可以提炼出一种更加特殊的抽象类——接口。接口里不能包含普通方法,接口里所有方法都是抽象方法。

2.1接口的概念

        接口是从多个相似类中抽象出来的规范,接口不提供任何实现。接口体现的是规范和实现分离的设计哲学。接口主要用来定义方法,规定必须具有的某些行为(方法),其它类如果想拥有次功能,就必须实现该接口。

定义格式:

       [修饰符] interface 接口名 extends 父接口1,父接口2,…{

               零到多个常量的定义

               零到多个抽象方法的定义

               零到多个内部类 接口 枚举定义

               零到多个默认方法或类方法定义(java8对接口进行了改进,允许接口中定义默认方法,默认方法可以提供方法实现

        }

2.2接口中的成员

        由于接口定义的是一种规范,因此接口里不能包含构造器和初始化块定义。接口里可以包含成员变量(只能是静态常量)、方法、(只能是抽象实例方法类方法或默认方法)、内部类(包括内部接口枚举)。

         接口定义的是多个类共同的公共行为规范,因此接口里所有的成员,包括常量方法 内部类和内部枚举都是public访问权限。定义接口成员时,可以省略访问控制修饰符,如果指定访问控制修饰符,则只能使用public访问控制修饰符。

        1)静态常量:接口中定义的变量默认以public static final 修饰。

        2)内部类:默认以public static修饰。接口中定义的内部类内部接口 内部枚举默认都采用publicstatic修饰,不管定义时是否指定这两个修饰符,系统都会自动使用public static对它们进行修饰。

        3)方法:接口中定义的方法只能是抽象方法类方法或默认方法,如果不是定义默认方法,系统将自动为普通方法加上abstract修饰符;定义接口里的普通方法时,不管是否使用public abstract修饰符,接口里的普通方法总是使用public abstract来修饰。接口里的方法不能有方法体;但类方法和默认方法必须有方法体。

        4)默认方法:java8允许在接口中定义默认方法,默认方法必须使用default修饰,该方法不能使用static修饰。默认方法总是使用public修饰符,如果开发者没有指定public,系统会自动为默认方法添加public修饰符。

2.3接口的特点

      1)没有构造方法,不能实例化;

      2)接口只能继承接口,不能继承类。一个接口可以有多个直接父接口;

      3)接口里的方法全是抽象的,默认修饰符是public abstract;

      4)接口里的字段全是静态常量,默认修饰符public static final;

      5)接口里的内部类全是静态的,默认修饰符public static。

2.4接口和抽象类的区别

     相同点:1)都位于继承的顶端,用于被其它类实现或者继承

                      2)都不能实例化;

                      3)都可以定义抽象方法,其子类必须重写这些抽象方法;

     不同点:1)接口没有构造方法,抽象类有构造方法;

                      2)接口中不能包含初始化块,抽象类完全可以包含初始化块

                      3)接口中只能包含抽象方法 静态方法和默认方法,不能为普通方法提供方法实现,而抽象类既可以包含普通方法,又可以包含抽象方法;

                      4)一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口(弥补了java单继承的缺点)。

3内部类

3.1内部类概述

  3.1.1什么是内部类

      将类写在其它类的内部,可以写在其它类的成员位置或局部位置,写在其它类内部的类就称为内部类,包含内部类的类被称为外部类。

  3.1.2什么时候使用内部类

       在描述事物时,若一个事物内部还可能包含其它事物,这时就可以使用内部类来描述。

  3.1.3 内部类的分类

         成员内部类和局部内部类

         成员内部类分为两种:静态内部类和非静态内部类。使用static修饰的成员内部类是静态内部类,没有使用static修饰的成员内部类是非静态内部类。

3.2使用内部类

   3.2.1成员内部类定义格式

         class 外部类 {

                  修饰符 class 内部类 {

                  }

          }

     访问方式:外部类名.内部类名 变量名 = new 外部类名().new 内部类名();

     3.2.2非静态内部类

         当在非静态内部类的方法内访问某个变量时,系统优先在该方法内查找是否存在该名字的局部变量,如果存在就使用该变量;如果不存在就到该方法所在的内部类中查找是否存在该名字的成员变量,如果存在就使用该成员变量,如果不存在,就到该内部类所在的外部类中查找是否存在该名字的成员变量,如果存在,则使用该成员变量;如果依然不存在,则系统将出现编译错误:提示找不到该变量。

       非静态内部类的成员变量只在非静态内部类范围内可知的,不能被外部类直接使用。如果外部类需要访问非静态内部类的成员,则必须显示创建非静态内部类对象来调用访问其实例成员。

       根据静态成员不能访问非静态成员的规则,外部类的静态方法 静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量创建实例等。即,不允许在外部类的静态成员中直接使用非静态内部类。

       非静态内部类里不能有静态方法 静态成员变量 静态初始化块。

  3.2.3静态内部类

       如果使用static来修饰一个内部类,则这个类属于外部类本身,而不属于外部类的某个对象。因此使用static修饰的内部类被称为类内部类(静态内部类)。

       静态内部类可以包含静态成员,也可以包含非静态成员。根据静态成员不能访问非静态成员的规则,静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。即使是静态内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员。

3.3 局部内部类

       如果把一个内部类放在方法里定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。由于局部内部类不能在外部类的方法以外的地方使用,因此局部内部类不能使用访问控制修饰符和static修饰符修饰。

       局部内部类定义格式:

       class 外部类 {

             修饰符 返回值类型 方法名(参数) {

                   class 内部类 {

                   }

             }

        }

访问方式:在外部类方法中,创建内部类对象,进行访问

4.匿名内部类

      匿名内部类适合创建只需要使用一次的类

      定义格式:

       new 实现接口()|父类构造器(实参列表){

               //匿名内部类的类体

       }

       匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类或实现一个接口。

       匿名内部类规则:

      1)匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不能将匿名内部类定义成抽象类。

      2)匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器。但匿名内部类可以定义初始化块,可以通过实例初始化块来完成构造器需要完成的事情。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章