Java抽象类、接口和内部类

抽象类

抽象方法和抽象类 

抽象方法和抽象类必须使用abstract修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法 

规则如下:

抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体,只能有方法签名。

抽象类不能被实例化。 无法使用new关键字来实例化类。

抽象类可以包含成员变量,方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类5种成分。抽象类的构造器不能用于创建实例,主要用于被其子类调用

含有抽象方法的类(包括直接定义和从父类继承)只能被定义成抽象类

抽象类概括起来有得有失:得指的是可以包含抽象方法,失的是不能用于创建instance

注意:

1、final和abstract永远不能同时使用

2、static和abstract不能同时修饰某个方法,但可以同时修饰某个内部类

3、private和abstract不能同时修饰方法

接口 

从多个类中更彻底的提炼出一种更加特殊的“抽象类”——接口,接口定义了一种规范,接口定义了某一批类所需要遵守的规范。

接口体现的是分离和实现分离的设计哲学。

接口中允许定义默认方法(default修饰),私有方法和类方法,这些方法都可以提供方法实现。

Java9中接口的定义

[修饰符] interface 接口名 extends 父接口1,父接口2...
{
    零个到多个常量定义
    零个到多个抽象方法定义
    零个到多个内部类,接口,枚举定义
    零个到多个私有方法,默认方法或类方法定义
}

修饰符可以是public或者省略,省略则默认采用包权限访问控制符,即只有同包可以访问该接口 。

接口名与类名采用相同的命名规则

一个接口可以有多个父接口,但接口只能继承接口

由于接口是一种规范,所以接口里不能包含构造器和初始化块定义。

Java9为接口新增一种新的私有方法,私有方法不能使用default修饰,可以使用static修饰,也就是说私有方法可以是类方法也可以是实例方法

对于接口里定义的静态常量而言,系统会自动增加public static final修饰符。

对于普通方法,系统会自动增加public abstract来修饰。

接口的继承

接口支持多继承

使用接口 

 接口不能用于创建实例,但可以用于声明引用类型变量

接口主要有如下用途 :
定义变量,也可用于进行强制类型转换。

调用接口中定义的常量。

被其他类实现。

类实现接口语法格式如下:

[修饰符] class 类名 extends 父类 implements 接口1,接口2...
{
    类体部分
}

实现接口与继承父类相似,一样可以获得所实现接口里定义的常量,方法。

实现接口方法时,必须使用public访问控制修饰符,因为接口里的方法都是public的,而子类重写父类方法时访问权限只能更大或相等,所以实现类实现接口只能使用public访问权限 

 接口和抽象类 

接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。

接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。

二者的区别:

接口作为系统与外界交互的窗口,接口体现的是一种规范。对于接口的实现者而言,接口规定了实现者必须向外提供哪些服务;对于接口的调用者而言,接口规定了调用者可以调用哪些服务,以及如何调用这些服务。但一个程序使用接口时,接口是多个模块间的耦合标准。当在多个程序之间使用接口时,接口是多个程序之间的通信标准

抽象类作为系统中多个子类的父类,体现的是一种模板式设计。

在使用方法上也有区别:

1、接口里只能包含抽象方法,类方法,默认方法和私有方法 ,不能为普通方法提供方法实现,而抽象类则完全可以包含普通方法

2、接口里只能定义静态常量,不能定义普通成员变量;抽象类则都可以

3、接口里不包含构造器;抽象类里可以包含构造器。

4、接口里不包含初始化块,抽象类则可以

面向接口编程

1、简单工厂模式 详见书P198

2、命令模式 详见书P200

内部类

定义在其他类内部的类就被称为内部类。

内部类的作为:

1、内部类提供了更好的封装

2、内部类成员可以直接访问外部类的私有数据

3、匿名内部类适合用于创建那些仅需要一次使用的类

外部类的上一级程序单元是包所以它只有两个作用域:同一个包内和任何位置。因此只需要省略访问控制符和public。而内部类上一级程序单元是外部类,它就具有四个作用域:同一个类(private),同一个包(default),父子类(protected),任何位置(public) 

非静态内部类 

详细看《java疯狂讲义》P202

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

非静态内部类对象和外部类对象的关系:

非静态内部类对象必须寄生在外部类对象里,而外部类对象则不一定有非静态内部类对象寄生其中。因此外部类对象访问非静态内部类成员时,可能非静态内部类对象根本不存在。

非静态内部类中不允许定义非静态成员

静态内部类 

静态内部类的实例方法也不能访问外部类的实例属性:静态内部类是外部类的类相关的,而不是外部类的对象相关的。当静态内部类对象存在时,并不存在一个被它寄生的外部类对象,静态内部类对象只持有外部类的类引用,没有对象引用。

外部类依然不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类成员

除此之外允许在接口中定义内部类,接口里定义的内部类默认使用public static修饰,也就是说接口里只能是静态内部类。

使用内部类

1、在外部类内部使用内部类

2、在外部类以外使用非静态内部类

OuterClass.InnerClass varName

在外部类以外的地方使用内部类时,内部类完整的类名应该是OuterClass.InnerClass。如果外部类有包名,则还应该增加包名前缀。

创建非静态内部类实例的语法:

OuterInstance.new InnerConstructor()
new OuterConstructor().new InnerConstructor()

 3、外部类以外使用静态内部类

因为静态内部类是外部类类相关的,因此创建静态内部类对象时无须创建外部类对象

new OuterClass.InnerConstructor()

 匿名内部类

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

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

}

关于匿名内部类有如下两条规则:

1、匿名内部类不能时抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。

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

如果局部变量被匿名内部类访问,在Java8以后,该局部变量自动使用了final修饰。 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值