JavaSE--抽象类、内部类、接口

一、抽象类

  当事物不能具体描述时可将事物抽象化,只对其应有的行为进行简单的描述而不进行深度具体的描述,这样就产生了抽象类,使用abstract关键字对类进行修饰内部方法也是用abstract进行描述。

1.特点

  抽象方法只能定义在抽象类中且不能有方法体,抽象类不能被实例化不能使用new关键字创建对象,它的子类覆盖所有的抽象方法后子类才能实例化,如果子类继承了抽象类却没有覆盖抽象方法那么子类也是抽象类,抽象类中可以存在非抽象方法即已经实现的方法可供子类覆盖或使用。

2.误区

  抽象类中存在构造函数,仅为子类的对象来进行实例化;抽象类一定是父类需要子类继承抽象类并覆盖抽象方法;抽象类可以不定义抽象方法,仅仅是让该类不能实例化;abstract与final、private、static不能共存;抽象类可以不包含抽象方法,包含抽象方法的类一定是抽象类,抽象类中的属性定义与一般类相同。

、接口(interface)

  接口主要就是方法定义和常量值的集合,接口是一种特殊的抽象类,这种抽象类里面的方法全部都是抽象方法。对于一个接口来说他没有构造器,所以他的变量只能定义成静态常量,这样就不要使用构造器对变量进行初始化了。

1.特点

  • 接口不可以被实例化,子类需要覆盖所有的抽象方法才能实例化,否则该子类还是个抽象类,接口是用来被实现的。
  • 类不能多继承的原因是当两个父类中出现相同的方法声明与实现时子类调用该方法会产生不确定性,这是由方法主体导致的,而接口可以多继承的原因是因为接口中的方法只有声明没有被实现没有方法主体,当两个父接口被实现时子类覆盖父接口同名方法时会默认认为那是一种行为方法的定义所以只会实现一次同名方法。继承的本质是获取体系的基本功能,想要扩展功能就需要通过实现不同的接口来实现。
  • 接口与接口之间具备继承关系不具备实现关系,并且接口可以多继承(因为只有方法声明没有方法主体所以不会发生冲突),接口是没有构造方法的(原因在于它的成员属性都是常量)。
  • 接口是暴露出来的规则,需要使用者去实现这一规范。

2.接口与类区别

  • 接口中常见成员有两种:全局常量、抽象方法;而且都有固定修饰符共性:成员都是使用public修饰的,编译时默认检查自动提供public;
  • 成员定义方法:public static final int MAX = 5;
  • 方法定义:public abstract void fun();

、内部类

  在类的内部定义一个或多个该类所属的类叫做内部类,内部类相当于外部类的成员,可以随意访问外部类中的成员,但外部类要访问内部类时需要创建内部类的实例来访问,在main方法中内部类是需要前缀的即外部类名+“.”+内部类名即为内部类的引用类型(Text.Inner ti = new Text().new Inner();)内部类的重要作用在于为多重继承提供支持。

  当一个类中有一个内部类时编译完成时会产生两个class文件其中包含内部类的class文件命名规则为:外部类名@内部类名,使用外部类名@1内部类称为局部内部类,因为该类处于局部方法当中,因为内部类会被原则上的与外部类分离所用创建外部类对象时内部类是不会加载的;

  内部类不允许访问所在局部的局部变量因为声明周期不一样,局部内部类只能访问被final修饰的局部变量;内部类需要访问与外部类同名的成员变量时需要使用类名加this确定具体对象(Inner.this;Outer.this)。

1.匿名内部类

  匿名内部类是一个简化的内部类,其中内部类需要继承或实现外部类或者接口,格式:new 父类名或者接口名(){子类内容}.子类成员;匿名内部类常出现的场所是方法体或属性初始化处。

2.非静态内部类

  非静态内部类没有无参构造器,它的默认构造器需要一个外部类实例参数,这也符合非静态内部类的规则:非静态内部类必须寄生在外部类的实例中,没有外部类对象就不存在非静态内部类对象。当在外部类内部显示的使用new Inner();来创建内部类时虚拟机底层也会将当前this作为实参传入构造器!显示的在内部类中声明无参构造器在编译时也将生成对应的有参构造器并隐式的调用它,显示定义一个带String参数的有参构造器编译时还将自动携带一个外部类参数!由此可见非静态内部类对外部类的依赖有多高!

  非静态内部类处于一个非静态的上下文环境,因此非静态内部类不允许拥有静态成员,只允许定义静态成员常量(static final)。

3.静态内部类

  静态内部类,定义在类中,任何方法外,用static定义;静态内部类只能访问外部类的静态成员生成一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:Outer.Inner in=new Outer.Inner();而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类,当然它还可以定义成私有静态内部类。

4.静态内部类与非静态内部类的区别

  • 普通内部类可以访问其外部类的各种类型成员,但是静态内部类只能访问静态成员
  • 普通内部类里面不能定义各种静态的成员(包括静态变量、静态方法、静态代码块和静态内部类),而静态内部类中则可以;

①静态变量和静态方法会出现这个语法错误(static methods can only be declared in a static or top level type)意思就是static方法只能在静态或者顶级类型(顶级类型应该就是外部类中)中声明,当然static变量和static内部类也是一样的道理。原因在静态变量和静态方法都只需要通过类名就能访问,不必通过任何实例化对象;而普通内部类的初始化要利用外部类的实例化对象,这明显违背了static的设计初衷。

②静态代码块会出现这个语法错误(Cannot define static initializer in inner type Outer.Inner)意思是不能在内部类中定义静态的初始化程序。原因跟以上的差不多,static声明的成员只能为类所共有,而不能仅属于一个实例化对象,通俗点来说就是不管有多少层的引用,都只能是类来引用而不能是对象。

posted @ 2018-08-01 23:05  北海之北  阅读(195)  评论(0编辑  收藏  举报