最具影响力的数字化技术在线社区

168大数据

 找回密码
 立即注册

QQ登录

只需一步,快速开始

1 2 3 4 5
打印 上一主题 下一主题
开启左侧

java 系列教程:(9)接口、内部类、枚举类、对象与垃圾回收

[复制链接]
跳转到指定楼层
楼主
发表于 2018-1-23 15:34:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多数据大咖,获取更多知识干货,轻松玩转大数据

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
1 接口#
1.1 接口的语法
接口(interface)是抽象方法和常量值的定义的集合
从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
从语义上理解为对象具备的某种能力,是对行为的抽象
一个类可以实现多个接口,接口也可以继承其它接口

file

file

file

file

file

file

file

file

file

file

file

file

file

file

1.1.2 接口特性

1)接口中的所有成员变量都默认是由public static final修饰的
2)接口中的所有方法都默认是由public abstract修饰的
3)接口没有构造器
4)接口采用多继承机制
5)如果实现接口的类中没有实现接口中的全部方法,必须将此类定义为抽象类
1.1.3 接口与多态
有了接口的多继承特性,加上一个类能够实现多个接口,这样,接口结合多态,语法和概念都变得非常的灵活

例如:
首先定义一个 Teacher 接口:

file

file

file

file

file

在注意在上面的代码中的两个方法。首先, getTeacher 方法的返回值为一个 Teacher 对象。
由于 Teacher 类型是一个接口类型,因此不会返回一个真正的接口对象,而返回的对象一定是接口的某一个实现类的对象。是把多态用在方法的返回值类型上。
2.1 接口的作用
1.2.1 接口与多继承
在 Java 中,能够很容易的区分一个类的主要类型和次要类型。
怎么来理解“主要类型”和“次要类型”呢?
例如:

file

对于“移动硬盘”来说。我们购买移动硬盘的主要目的,是为了存储数据。因此,“存储设备”是其主要类型。当然,为了让设备与电脑主机之间能够更加方便的交互,让移动硬盘实现“ USB 设备”这个接口也是非常必要的。然而,相对于存储数据,用 USB 连接是一个次要的功能,因此,相对于“存储设备”,“ USB 设备”这是一个次要类型。
我们把“ USB 设备”定义为一个接口, 就可以区分主要类型和次要类型。

我们可以让一个类继承自其主要类型,而次要类型,可以作为接口,让这个类来实现。
又例如:
对于 SpiderMan(蜘蛛侠) 这个类来说,产生这个类的原因是一个 Man 类的对象受到了一些外界的影响(蜘蛛侠具有蜘蛛能力的原因,是因为小时候被蜘蛛咬了一口),产生了变化,从而实现了 Spider 接口。
在这个过程中, Man 是主要类型,而 Spider(蜘蛛) 是次要类型,是接口。

file

单继承相对多继承的好处,就在于单继承具有简单性。使用单继承,类与类之间能够形成简单的树状结构。
而对于多继承,类和类之间的关系相对要复杂的多,很有可能会形成复杂的网状结构。
但是,用接口实现的多继承,则不会破坏类之间树状结构的简单性。
这是因为这棵树是由类之间形成的,是事物主要类型所组成的关系。
一个类实现再多的接口,有再多的次要类型,也不会改变其主要类型之间的树状结构。
1.2.2 接口与解耦合

file

除了实现多继承之外,接口最重要的作用就是解耦合。 什么叫解耦合呢?我们看下面这段代码的例子。

file

在上面的代码中, lamp 的 on 方法,调用了 bulb 的 shine 方法。 也就是说,当我们调用台灯对象的“开”方法时,台灯对象会去调用灯泡对象的发光方法。
但是,问题来了:现在的这个台灯,装的是红灯泡。如果现在想要把红灯泡换成绿灯泡,应当如何操作呢?
由于 Lamp 类中的 bulb 属性是 RedBulb 类型,因此,一旦要修改,则必须要把 Lamp类中的属性类型进行修改,并且修改 setBulb 方法的相应参数和实现。 也就是说,当我们希望把 bulb 属性由 RedBulb 替换为 GreenBulb 的时候,必须修改 Lamp 类的代码。
也就是说,如果要想更换不同种类的灯泡,就要修改台灯的内部结构!这无疑是跟现实生活不相符合的。之所以产生这样的矛盾,原因在于 Lamp 类与 RedBulb 类型紧密联系在一起,形成了强耦合的关系,如下图:

file

file

file

Lamp 类的 bulb 属性被改为接口类型 Bulb,从而, Lamp 类与具体的实现类之间用 Bulb接口分离开了。 当 Lamp 类希望把 bulb 属性由 RedBulb 对象变更为 GreenBulb 对象时,不需要修改任何自身代码。只需要调用 setBulb 方法,接受不同的 Bulb 接口的实现类就可以了,从而, Lamp 类通过 Bulb 接口,实现了与 Bulb 实现类的弱耦合。如下图所示:

file

把原来强耦合的关系,变为了弱耦合的关系。这就是接口最重要的作用:解耦合。

    由于接口中所有的方法都是抽象方法,因此,定义一个接口,可以看作是定义了一个标准。它只定义了,一个对象应该具有哪些方法,而丝毫没有定义对象如何实现这些方法。方法的实现统统交给接口的实现类来完成。
    这样,接口的出现,就阻隔了接口使用者和接口实现者之间的耦合关系。当接口实现者变化的时候,对接口使用者不产生任何影响。
1.3 抽象类与接口的区别

file

方法实现:方法是个抽象方法,通过子类或实现接口的方式,实现该方法(重写)

抽象类中有普通方法,接口没有普通方法。

1.3.1 什么时候使用抽象类和接口
1)如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
2)如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
3)如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。
1.4 设计模式——简单工厂与工厂方法模式
1.4.1 简单工厂
例子:用户输入两个数 和 运算符号【“+”、“-”、“*”、“/”】之一,得到相应的运算结果。

file

其中:
运算类:是一个抽象类,有两个属性值,和一个抽象运算方法。
下面四个类是继承抽象类,用多态实现运算结果。
简单工厂类:有个创建运算类的方法,根据运算符创建不同的运算类对象实例。

file

依赖:
可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、、临时性的、非常弱的,但是B类的变化会影响到A;比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖;表现在代码层面,为类B作为参数被类A在某个method方法中使用。用带虚线的箭头。

file

总结:
简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。如果要在运算里加取余或平方运算,需要在工厂里增加case 分支语句,修改 了原来的类,有点违反开放封闭原则。为了可扩展,采用工厂方法改写。
开放封闭原则:软件实体应该可以扩展,但是不可以修改。它有两个特性:对扩展开放,对修改封闭。

1.4.2 工厂方法
工厂方法模式:
定义一个用于创建对象的接口,让子类决定示例化哪一个类。工厂方法是使一个类的实例化延迟到其子类。

file

file

file

2 内部类#
内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。
内部类主要有以下几类:非静态内部类、局部内部类、静态内部类、匿名内部类。
内部类定义语法格式:

file

编译程序后,会看到所在路径生成两个class文件
一个是 OuterClass.class,也就是外部类 OuterClass 的 class 文件。
另一个是 OuterClass$InnerClass.class ,也就是内部类 InnerClass 的文件。
成员内部类是一种与属性、方法、构造方法和初始化块相似的类成员;
局部内部类和匿名内部类不是类成员。

file

2.1 非静态内部类
非静态内部类:没有static修饰的成员内部类。

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

如果内部类中没有与外部类同名的变量,则可以直接用变量名访问外部类变量。

内部类如果访问外部类成员变量、内部类成员变量与内部类方法的局部变量同名时,
访问内部类方法的局部变量:变量名
访问内部类成员变量:this.变量名
访问外部类成员变量:外部类名.this.变量名
为什么能用Outer.this找到外部类的成员变量

2.2 局部内部类
如果把内部类放到外部类的方法里,这个内部类就是局部内部类。
局部内部类不能使用访问控制符和 static 修饰。
代码示例:

2.3 静态内部类
有static 修饰的成员内部类,就是静态内部类。
静态内部类属于外部类的本身,而不属于外部类的某个实例对象。
静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。即使是内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员。

3.4 匿名内部类
匿名内部类
没有名字的内部类,正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写。
使用匿名内部类前提条件
必须继承一个父类或实现一个接口
不使用匿名内部类来实现抽象方法

file

file

file

file

file

3.5 枚举类型增加构造器
枚举类构造器只能用 private 访问控制符

代码示例:
创建带有构造方法的枚举类

4 对象与垃圾回收#
4.1 对象在内存中的状态
1)可达状态
当一个对象被创建后,有一个以上的引用变量引用它。在有向图中可以从起始顶点导航到该对象,那么它就出于可达状态,程序可以通过引用变量来调用该对象的属性和方法。
2)可恢复状态
如果程序中某个对象不再有任何引用变量引用它,他将进入可恢复状态,此时从有向图的起始顶点不能导航到该对象。在这种状态下,系统的垃圾回收机制转变回收该对象所占用的内存。在回收该对象之前,系统会调用可恢复状态的对象的finalize方法进行资源清理,如果系统调用finalize方法重新让一个以上的引用变量引用该对象,则该对象会再次编程可达状态;否则,该对象将进入不可达状态。
3)不可达状态
当对象的所有关联都被切断,且系统调用所有对象的finalize方法依然没有使该对象变成可达状态后,这个对象将永久性地失去引用,最后变成不可达状态。只有当一个对象出于不可达状态,系统才会真正回收该对象所占用的资源。

file

4.2 强制垃圾回收
调用 System 类的 gc() 静态方法:System.gc()
调用 Runtime 对象的 gc() 实例方法:Runtime.getRuntime().gc()
这种强制只是建议系统立即进行垃圾回收,系统完全有可能建议完全置之不理,垃圾回收机制会在收到通知后,尽快进行垃圾回收。
4.3 finalize 方法
Object类的finalize()方法。
finalize 方法的特点

    1)永远不要主动调用某个对象的finalize 方法,该方法应交给垃圾回收机制调用。finalize 方法何时被调用,是否被调用具有不确定性,不要把finalize 方法当成一定会被执行的方法。
    2)在 JVM 的规范中,只规定了 JVM 必须要有垃圾回收机制,但是什么时候回收却没有明确说明。也就是说,对象成为了垃圾对象之后, 并不一定会马上就被垃圾回收。
    3)Sun 公司采用的垃圾回收的方式,是“最少回收” 的方式:只有当内存不够的时候才会进行垃圾回收。
    4)当JVM执行finalize 方法时出现异常时,垃圾回收机制不会报告异常,程序继续执行。
目前已有很多用户,建议抛弃Object 类的 finalize 方法。

总结:
任何java类都可以重写Object类的finalize方法。
finalize 方法在对象被垃圾回收的时候调用。
但是,由于 Sun 公司的 JVM 采用的是“最少”回收的机制,因此不应当把释放资源的代码写在 finalize 方法中。

版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海牛部落-海牛博士,http://hainiubl.com/topics/154hainiubl.com
楼主热帖
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 赞 踩

168大数据 - 论坛版权1.本主题所有言论和图片纯属网友个人见解,与本站立场无关
2.本站所有主题由网友自行投稿发布。若为首发或独家,该帖子作者与168大数据享有帖子相关版权。
3.其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和168大数据的同意,并添加本文出处。
4.本站所收集的部分公开资料来源于网络,转载目的在于传递价值及用于交流学习,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
5.任何通过此网页连接而得到的资讯、产品及服务,本站概不负责,亦不负任何法律责任。
6.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源,若标注有误或遗漏而侵犯到任何版权问题,请尽快告知,本站将及时删除。
7.168大数据管理员和版主有权不事先通知发贴者而删除本文。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

关于我们|小黑屋|Archiver|168大数据 ( 京ICP备14035423号|申请友情链接

GMT+8, 2024-5-8 05:43

Powered by BI168大数据社区

© 2012-2014 168大数据

快速回复 返回顶部 返回列表