《Java编程思想》学习笔记【一对象导论】

重头学习Java,大一没怎么学,大二上课也没听。(流下不学无术的眼泪)


所有编程语言都提供抽象机制,我们所能解决的问题的复杂性直接取决于抽象的类型和质量
汇编语言是对底层机器的轻微抽象,“命令式”语言(BASIC,C等)是对汇编语言的抽象,但它们所作的主要抽象仍要求在解决问题时要基于计算机的结构,而不是基于所要解决的问题的结构来考虑。

而面向对象方式通过提供表示问题空间中的元素的工具更进一步。我们将问题空间中的元素及其在解空间(对问题建模的地方,例如计算机)看中的表示称为“对象”。
这种思想实质:程序可以通过添加新类型的对象使自身适用于某些特定问题。
因此当你阅读描述解决问题的代码的同时,也是在阅读问题的表述。

有人总结了第一个面向对象语言,同时也是Java所基于的语言之一的Smalltalk的五个基本特性:

  • 万物皆为对象:理论上,你可以抽取待求解问题的任何概念化构件,将其表示为程序中的对象。
  • 程序是对象的集合,它们通过发送消息来告知彼此所要做的:消息相当于某个特定对象的方法的调用请求。
  • 每个对象都有自己的由其他对象所构成的存储:可以通过创建包含现有对象的包的方式来创建新的对象。因此可以构建复杂体系,同时将其复杂性隐藏在对象的简单性背后。
  • 每个对象都拥有其类型:每个对象都是某个类(class)的一个实例(instance)。
  • 某一特定类型的所有对象都可以接受同样的消息:比如发给几何形对象的消息,圆形对象也可以接收到。



抽象数据类型的运行方式与内置类型几乎完全一致:你可以创建某一类型的变量(按面向对象说法,称其为对象或实例),然后操作这些变量(称其为发送消息或请求)。
每个类的成员或元素都具有某种共性(每个账户都有结余金额,每个出纳都可以处理存款请求),同时每个成员都有其自身状态(每个账户结余金额不同,每个出纳都有自己的姓名)。因此,(出纳,客户,账户等)都可以在计算机程序中被表示成唯一实体**。这些实体就是对象,每个对象都属于定义了特性和行为的某个特定类**。
类描述了具有相同特性(数据元素)和行为(功能)的对象集合,所有一个类实际上就是一个数据类型。
程序通过定义类来适应问题。


一个类被建立,就可以随心使用创建类的任意个对象,去玩弄 操作它们了 。
但是怎样才能获得有用的对象呢?
必须有某种方式产生对对象的请求,使对象完成各种任务(如打开开关,完成某笔交易等)。每个对象都只能满足某些请求,这些请求由对象的接口(interface)定义。
接口确定了对某一特定对象所能发出的请求,满足请求的代码和隐藏的数据构成实现。



当试图开发或理解一个程序设计时,最好将对象想象成“服务提供者”。有助于提高对象的内聚性。(高聚性是软件实际的基本质量要求之一。)
如何做:思考如果我可以将问题从表象中抽取出来,那么什么样的对象可以解决问题呢?


我们一般将程序开发人员按角色分为类创建者(即创建新数据类型的程序员)和客户端程序员(即在应用中使用数据类型的类消费者)。
因为两者目标不一样,我们需要访问控制
访问控制存在的原因:

  • 让客户端程序员无法触及到他们不该触及的部分。
  • 允许库设计者可以改变类内部的工作方式而不用担心会影响客户端程序员(接口和实现分离并得以保护,就可以轻松做到)。

Java用三个关键字在类的内部设定边界:public,private,protected
public表示紧随其后的元素对任何人都是可用的。
private表示除类型创建者和类型的内部方法外的任何人都不能访问的元素。
protected和private相当,只是继承的类可以访问protected成员。
Java还有一种默认访问权限(包访问权限),当前面没有使用前面提到的任何访问指定词时,它发挥作用:类可以访问在同一个包中的其他类的成员。



代码复用是面向对象的优点。
最简单的复用某个类就是直接创建该类的一个对象,也可以将那个类的一个对象置于某个新类中
因为是在使用现有的类合成新类,所以也被称为组合,新类的成员对象通常被声明为private,使得使用新类的客户端程序员不能访问他们。(因此可以再不干扰现有客户端代码的情况下,修改这些成员,也可以在运行时修改)
如果组合是动态发生的,那么通常被称为聚合。(has-a拥有关系)


继承相当于我们以现有的类为基础,复制它,然后通过添加和修改这个副本来创建新类。
一个基类型包含其所有导出所共享的特性和行为
当继承现有类型时,也就创造了新的类型,新类型不仅包括现有类型的所有成员(尽管private成员被隐藏起来,并且不可访问),而且它复制了基类的接口(即所有可以发送给基类对象的消息同时也可以发送给导出对象。)

有两种方法可以使基类与导出类产生差异:

  • 直接在导出类添加新方法
  • 改变现有基类的方法的行为(即覆盖

继承如果只覆盖基类的方法(不添加新方法),意味着导出类和基类是完全相同的类型,因为他们具有完全相同的接口。(结果导致可以用一个导出类对象完全替代一个基类对象,这被视为纯粹替代),我们将这种情况下的基类与导出类之间的关系成为(is-a是一个关系)。 如果在导出类型添加新的接口元素(即扩展了接口),这种成为(is-like-a像是一个关系)

在处理类型的层次结构时,经常把一个对象当做其基类的对象来对待。(这使得人们可以编写出不依赖于特定类型的代码)
举例:在几何形例子中,方法操作的都是泛化的形状,我们不关心她们是圆形还是正方形或者其他,所有的几何形状都可以被移动,绘制。
面向对象秒在:编译器不可能产生传统意义上的函数调用
一个非面向对象编程的编译器产生的函数调用会引起前期绑定(即编译器将产生对一个具体函数名字的调用,而运行时将这个调用解析到将要被执行的代码的绝对地址)。
然而在OOP中,程序直到在运行时才能够确定代码的地址。
于是面向对象程序设计语言使用了后期绑定的概念。编译器只要确保被调用方法的存在,并对调用参数和返回值执行类型检查。(不用知道被执行的确切代码)
为了执行后期绑定,Java使用一小段特殊代码来替代绝对地址调用,这段代码使用在对象中储存的信息来计算方法体的地址。【详情请看《Java编程思想》学习笔记【八】】
ps.c++必须声明希望某个方法具备后期绑定属性所带来的灵活性(使用virtual关键字),而java动态绑定是默认行为。
在这里插入图片描述
在这里插入图片描述
图上将导出类看做是它的基类的过程被称为向上转型
基于多态,对象知道执行什么样的正确行为。



单根继承结构:所有的类最终都继承自单一的基类,在Java中是Object。
这种单根继承结构使垃圾回收器的实现变得容易得多,由于所有对象都保证具有其类型信息,因此不会因无法确定对象类型二陷入僵局。(这对系统级操作(如异常处理)显得尤其重要)


通常你不知道解决某个特定问题需要多少个对象,需要多少空间。
因为这些信息只有在运行时才能知道,所以我们选择创建另一种对象类型(通常被称为容器集合),这种类型持有对其他对象的引用。
Java具有不同容器:List(储存队列),Map(关联数组,用来建立对象之间的关联),Set(每种对象类型只持有一个),以及队列,树,堆栈等更多构件

  • 不同容器提供了不同类型的接口和外部行为。
  • 不同容器对某些操作有不同效率。【比如ArrayList和LinkedList】

当java SE5出现前,容器只能储存Object对象,而单根继承结构意味着所有东西都是object类型,所以可以储存object的容器可以储存任何东西。
使用时:先向上转型成object放入容器,取回时再向下转型。(向下转型有风险,除非你知道所要处理的对象的类型)

因为向下转型很烦,所以创建了这样的容器:知道自己所保存的对象的类型。这种解决方案被称为参数化类型机制
参数化类型就是一个编译器可以自动定制作用于特定类型上的类
java SE5增加了参数化类型(称为范型
在这里插入图片描述



每个对象为了生存都需要资源,尤其是内存。当我们不需要一个对象时,必须要让它占有的资源可以被释放和重用。

C++认为效率控制是最重要的议题,通过将对象置于堆栈(也被叫自动变量)或静态储存区域来实现。这种方式将储存空间分配和释放置于优先考虑的位置,但是牺牲了灵活性(因为编写时必须知道对象确切数量,生命周期和类型)。
第二种方式是在堆(heap)的内存池中动态创建对象。因为储存空空是在运行中被动态管理的,所以需要大量时间在堆中分配储存空间。
在这里插入图片描述
Java采用了动态内存分配方式,使用new关键字来构建新对象的动态实例
对于允许在堆栈上创建对象的语言,编译器可以确定对象存活时间,并自动销毁,然而在堆上创建对象,编译器就对生命周期一无所知。(c++就需要编程确定何时销毁对象,但可能不能正确处理而导致内存泄漏
而Java有垃圾回收器。


异常是一种对象,从出错点被“抛出”,并被专门设计用来处理特定类型错误的相应的异常处理器“捕获”。
异常处理不会干扰正常的执行代码,异常也不能被忽略,保证一定会在某处得到处理。
一场提供了一种从错误状况进行可靠恢复的途径。
异常处理不是面向对象的特征。(异常处理在面向对象出现之前就已经存在)



并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。
在程序中,彼此独立运行的部分称之为线程。通常线程只是一种为单一处理器分配执行时间的手段。
如果有多个

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值