本章内容
- 语言发展史
- 面向对象概念
- 面向面向对象的三大核心特性
- 类与对象概念
- 对象的几种创建方式
1.0 语言发展史
1.1 关于计算机
计算机发展一共有四个发展阶段:
第一代计算机 特征是采用电子管作为主要元器件
第二代计算机 特征是采用晶体管作为主要器件
第三代计算机 特征是半导体中小规模集成电路
第四代计算机 特征是大规模和超大规模集成电路
1.2 第一台计算机
世界上第一台电子计算机是个庞然大物:重30余吨,占地约170平方米,肚子里装有18000只电子管。它是1946年2月14日,在美国宾夕法尼亚大学诞生的。
在第二次世界大战中,敌对双方都使用了飞机和火炮,猛烈轰炸对方军事目标。要想打得准,必须精确计算并绘制出"射击图表"。经查表确定炮口的角度,才能使射出去的炮弹正中飞行目标。但是,每一个数都要做几千次的四则运算才能得出来,十几个人用手摇机械计算机算几个月,才能完成一份"图表"。针对这种情况,人们开始研究把电子管作为"电子开关"来提高计算机的运算速度。许多科学家都参加了实验和研究,终于制成了世界上第一台电子计算机,起名为"埃尼阿克"。
20世纪40年代中期,美国宾夕法尼亚大学电工系由莫利奇和艾克特领导,为美国陆军军械部阿伯丁弹道研究实验室研制了一台用于炮弹弹道轨迹计算的“电子数值积分和计算机”(Electronic Numerical Integrator and Calculator简称ENIAC)。这台叫做“埃尼阿克”的计算机占地面积150平方米,总重量30吨,使用了18000只电子管,6000个开关,7000只电阻,10000只电容,50万条线,耗电量140千瓦,可进行5000次加法/秒运算。这个庞然大物于1946年2月15日在美国举行了揭幕典礼。这台计算机的问世,标志着电脑时代的开始,据传言,当时这台计算机一开机,整个镇的用电都瘫痪了。
电脑的发明是一群科研人员共同努力的成果,但其中数学家冯·诺依曼的设计思想在其中起到了关键作用,所以冯·诺依曼被称为现代计算机之父。
艾伦·麦席森·图灵(英语:Alan Mathison Turing,1912年6月23日—1954年6月7日)
英国数学家、逻辑学家,被称为计算机科学之父,人工智能之父。1931年图灵进入剑桥大学国王学院,毕业后到美国普林斯顿大学攻读博士学位,第二次世界大战爆发后回到剑桥,后曾协助军方破解德国的著名密码系统Enigma,帮助盟军取得了二战的胜利。
1952年,英国政府对图灵的同性恋取向定罪,随后图灵接受化学阉割(雌激素注射)。1954年6月7日,图灵吃下含有氰化物的苹果中毒身亡,享年41岁。2013年12月24日,在英国司法大臣克里斯·格雷灵的要求下,英国女王伊丽莎白二世向图灵颁发了皇家赦免。
图灵对于人工智能的发展有诸多贡献,提出了一种用于判定机器是否具有智能的试验方法,即图灵试验,至今,每年都有试验的比赛。此外,图灵提出的著名的图灵机模型为现代计算机的逻辑工作方式奠定了基础。
如果大家想进一步了解图灵的一生,推荐大家一部电影《模仿游戏》
关于图灵与冯·诺伊曼
计算机界最高奖项叫图灵奖,而将计算机之父的称号送给了冯诺依曼,这是为什么?这两位计算机发展史上的两位鼻祖的功绩,主要区别在何处?个人研学之后,结合自己设计计算机的收获,给出简单界限,正确与否会有定论。
搞程序设计的人或者软件程序员很难理解图灵,因为他们只要懂得冯诺依曼的程序数据存储的思想,会应用指令系统编程就可以了。这是因为指令别人已经为你设计好了,你不必去想如何设计指令。最早人们将机器的工作主要放到数学计算上,因而数学计算是焦点。图灵机解决的正是这个问题。在冯诺依曼计算机中,一种数学计算已经变成了一条指令。由此看来,图灵一不小心,创造了机器指令设计的基本方法,但是图灵的设计主要有个问题。第一,没能将指令存储起来重复使用。第二,没能形成实现程序结构设计。由于这两点缺欠,使图灵机还不能成为能够处理各种任务的计算机。图灵机欠缺的这两点恰被冯诺依曼提出的程序数据存储的思想解决了。
1.3 计算机语言的发展
计算机语言总的来说分为机器语言,汇编语言,高级语言三大类。而这三种语言也恰恰是计算机语言发展历史的三个阶段。
1946年2月14日,世界上第一台计算机ENAC诞生,使用的是最原始的穿孔卡片。这种卡片上使用的语言是只有专家才能理解的语言,与人类语言差别极大,这种语言就称为机器语言。机器语言是第一代计算机语言。这种语言本质上是计算机能识别的唯一语言,人类很难理解。以后的语言就是在这个的基础上简化而来。虽然后来发展的语言能让人类直接理解但最终送入计算机的还是这种机器语言。
计算机语言发展到第二代,出现了汇编语言。汇编语言用助记符代替了操作码,用地址符号或标号代替地址码。这样就用符号代替了机器语言的二进制码。汇编语言也称为符号语言。比起机器语言,汇编大大进步了。尽管还是复杂,用起来容易出错,但在计算机语言发展史上是机器语言向更高级的语言进化的桥梁。
当计算机语言发展到第三代时,就进入了“面向人类”的高级语言。高级语言是一种接近于人们使用习惯的程序设计语言。它允许用英文写计算程序,程序中的符号和算式也与日常用的数学式子差不多。高级语言发展于20世纪50年代中叶到70年代,流行的高级语言已经开始固化在计算机内存里了,比如 basic语言。现在,计算机语言仍然在不断的发展,种类也相当多,比如 FORTRAN语言, COBOL语言,C语言,C++,C#, PASCAO,JAVA等等。
1.4 Java语言发展
1995年5月23日,Sun在Sun World会议上正式发布Java语言和HotJava浏览器。IBM、Apple、DEC、Adobe、HP、Oracle、Netscape和Microsoft等各大公司都纷纷停止了自己的相关开发项目,竞相购买了Java使用许可证,并为自己的产品开发了相应的Java平台。
1996年1月,Sun公司发布了Java的第一个开发工具包(JDK1.0),这是Java发展历程中的重要里程碑,标志着Java成为一种独立的开发工具。
1996年4月,10个最主要的操作系统供应商申明将在其产品中嵌入Java技术。
1996年9月,约8.3万个网页应用了Java技术来制作。
1996年10月,Sun公司发布了Java平台第一个即时编译器(JIT)。
1997年2月18日,JDK1.1面世,在随后的三周时间里,达到了22万次的下载量。
1997年4月2日,JavaOne会议召开,参与者逾一万人,创当时全球同类会议规模之纪录。
1997年9月,JavaDeveloperConnection社区成员超过十万。
1998年2月,JDK1.1被下载超过2,000,000次。
1998年12月8,Java的企业平台Java EE正式发布。
1999年6月,Sun公司发布第二代Java的三大版本:标准版J2SE(Java2 Standard Edition):应用于桌面环境、企业版J2EE(Java2 Enterprise Edition):应用于基于Java的应用服务器、微型版J2ME(Java2 Micro Edition):应用于移动、无线及有限资源的环境。Java2的发布,标志着Java的应用开始普及,是Java发展历程中的又一个里程碑。
1999年4月27日,HotSpot虚拟机发布。HotSpot虚拟机发布时是作为JDK1.2的附加程序提供的,后来它成为了JDK1.3及之后所有版本的Sun JDK的默认虚拟机。
2000年5月8日,JDK1.3发布。
2000年5月29日,JDK1.4发布。获得Apple公司Mac OS的工业标准的支持。
2001年6月5日,NOKIA宣布,到2003年将出售1亿部支持Java的手机。
2001年9月24日,Java EE 1.3发布
2002年2月26日,J2SE1.4发布,自此Java的计算能力有了大幅提升,与J2SE1.3相比,其多了近62%的类与接口。在这些新特性当中,还提供了广泛的XML支持、安全套接字(Socket)支持(通过SSL与TLS协议)、全新的I/OAPI、正则表达式、日历与断言。
2004年9月30日18:00PM,J2SE1.5发布,是Java语言发展史上的又一里程碑事件。为了表示这个版本的重要性,J2SE 1.5正式更名为Java SE 5.0(内部版本号:1.5.0),代号“Tiger”该版本是自1996年发布1.0版本以来最大的更新,其中包括泛型的支持、基本数据类型的自动装箱、改进的循环、枚举类型、格式化I/O及可变参数。
2005年6月,在Java One大会上,Sun公司发布了Java SE 6。此时,Java的各个版本都已经更名,去掉了前些版本中的数字2,改为了Java。
2006年11月13日,Sun公司宣布,将Java技术作为免费的软件对外发布。Sun公司正式发布Java平台标准版的第一批源代码,以及mini版本的可执行源代码。一直以来,Sun公司维持着大约2年发布一次JDK新版本的习惯。
2007年3月,自起,全世界所有的开发人员均可对Java源代码进行修改。
2009年4月20日,Oracle宣布将以每股9.5美元的价格收购Sun,该交易的总价值约为74亿美元。但Oracle通过收购Sun公司获得了两项软件资产:Java和Solaris。于是曾经代表一个时代的公司:Sun倒下了,不过Java的大旗依然“猎猎”作响。2007年11月,Google宣布推出一款基于Linux平台的开源手机操作系统:Android。Android的出现顺应了即将出现的移动互联网潮流,而且Android系统的用户体验非常好,因此迅速成为手机操作系统的中坚力量。Android平台使用了Dalvik虚拟机来运行.dex文件,Dalvik虚拟机的作用类似于JVM虚拟机,只是它并未遵守JVM规范而已。Android使用Java语言来开发应用程序,这也给了Java语言一个新的机会。在过去的岁月中,Java语言作为服务器端编程语言,已经取得了极大地成功;而Android平台的流行,则让Java语言获得了在客户端程序上大展拳脚的机会。
2010年Java编程语言的创始人James Gosling从Oracle公司辞职。
2011年7月28日,Oracle公司终于发布了Java 7,这次版本升级经过了将近5年时间。Java 7也是Oracle发布的第一个Java版本,引入了二进制整数、支持字符串的switch语句、菱形语法、多异常捕捉、自动关闭资源的try语句等新特性
2014年3月18日,Oracle公司发布了Java 8,这次版本升级为Java带来了全新的Lambda表达式。除此之外,Java 8还增加了大量新特性,这些新特性使得Java变得更加强大。
2017年9月21日,Java 9发布。该版本支持:模块化(jiqsaw)、交互式命令行(JShell)、默认垃圾回收期切换为G1、进程操作改进、竞争锁性能优化、分段代码缓存和优化字符串占用空间等新特性。
2018年3月21日,Java 10发布。
2018年9月25日,Java 11发布。
目前Java的版本已经更新到12版本,但市场主流还是使用的JDK8。
2.0 面向对象概念
面向对象简称 OO(Object Oriented),20 世纪 80 年代以后,有了面向对象分析(OOA)、 面向对象设计(OOD)、面向对象程序设计(OOP)等新的系统开发方式模型的研究。
OOA: Object-Oriented Analysis[əˈnæləsɪs](面向对象分析方法)
是确定需求或者业务的角度,按照面向对象的思想来分析业务。
OOD: Object-Oriented Design[dɪˈzaɪn] (面向对象设计)
面向对象设计是OO方法中一个中间过渡环节。主要作用是对OOA结果作进一步的规范化整理,以便能够被OOP直接接受。
OOP:Object Oriented Programming(面向对象程序设计)
面向对象程序设计是一种计算机编程架构,OOP的一条基本原则是计算机程序由单个能够起到子程序作用的单元或对象组合而成,OOP达到了软件工程的三个主要目标:重用性、灵活性和扩展性。OOP=对象+类+继承+多态+消息,其中核心概念是类和对象。面向对象程序设计方法是尽可能模拟人类的思维方式,使得软件的开发方法与过程尽可能接近人类认识世界、解决现实问题的方法和过程,把客观世界中的实体抽象为问题域中的对象。面向对象程序设计以对象为核心,该方法认为程序由一系列对象组成。类是对现实世界的抽象,包括表示静态属性的数据和对数据的操作,对象是类的实例化。对象间通过消息传递相互通信,来模拟现实世界中不同实体间的联系。在面向对象的程序设计中,对象是组成程序的基本模块。对 Java 语言来说,一切皆是对象。把现实世界中的对象抽象地体现在编程世界中,一个对象代表了某个具体的操作。一个个对象最终组成了完整的程序设计,这些对象可以是独立存在的,也可以是从别的对象继承过来的。对象之间通过相互作用传递信息,实现程序开发。
3.0 面向面向对象的三大核心特性
面向对象开发模式更有利于人们开拓思维,在具体的开发过程中便于程序的划分,方便程序员分工合作,提高开发效率。面向对象程序设计有以下优点。
可重用性:代码重复使用,减少代码量,提高开发效率。下面介绍的面向对象的三大核心特性(继承、封装和多态)都围绕这个核心。
可扩展性:指新的功能可以很容易地加入到系统中来,便于软件的修改。
可管理性:能够将功能与数据结合,方便管理。
该开发模式之所以使程序设计更加完善和强大,主要是因为面向对象具有继承、封装和多态 3 个核心特性。
3.1 拓展关键词
三高:高并发、高性能、高可用
- 高并发是现在互联网分布式框架设计必须要考虑的因素之一,它是可以保证系统能被同时并行处理很多请求。
- 高性能是指程序处理速度非常快,所占内存少,cpu占用率低。
- 高可用通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性(集群)。
3.2 继承
如同生活中的子女继承父母拥有的所有财产,程序中的继承性是指子类拥有父类的全部特征和行为,这是类之间的一种关系。Java 只支持单继承。
例如定义一个语文老师类和数学老师类,如果不采用继承方式,那么两个类中需要定义的属性和方法如图所示。
从图中能够看出语文老师类和数学老师类中的许多属性和方法相同,这些相同的属性和方法可以提取出来放在一个父类中,这个父类用于被语文老师类和数学老师类继承。当然父类还可以继承别的类
提示:
C++ 支持多继承,多继承就是一个子类可有多个父类。例如,客轮是轮船也是交通工具,客轮的父类是轮船和交通工具。多继承会引起很多冲突问题,因此现在很多面向对象的语言都不支持多继承。Java 语言是单继承的,即只能有一个父类,但 Java 可以实现多个接口。
3.3 封装
封装是将代码及其处理的数据绑定在一起的一种编程机制,该机制保证了程序和数据都不受外部干扰且不被误用。封装的目的在于保护信息,使主要优点如下:
保护类中的信息,它可以阻止在外部定义的代码随意访问内部代码和数据。
隐藏细节信息,比如取款机中的键盘,用户只需要知道按哪个键实现什么操作就可以,至于它内部是如何运行的,用户不需要知道。
有助于建立各个系统之间的松耦合关系,提高系统的独立性。例如 U 盘,不管里面的存储方式怎么改变,只要U盘上的USB接口不变,就不会影响用户的正常操作。
提高软件的复用率,降低成本。每个系统都是一个相对独立的整体,可以在不同的环境中得到使用。例如,一个 U 盘可以在多台电脑上使用。
Java 语言的基本封装单位是类。由于类的用途是封装复杂信息,所以类的内部有隐藏实现复杂性的机制。Java 提供了私有和公有的访问模式,类的公有接口代表外部的用户应该知道或可以知道的每件东西,私有的方法数据只能通过该类的成员代码来访问,这就可以确保不会发生不希望的事情。
3.4 多态
面向对象的多态性,即“一个接口,多个方法”。多态性体现在父类中定义的属性和方法被子类继承后,可以具有不同的属性或表现方式。多态性允许一个接口被多个同类使用,弥补了单继承的不足。多态概念可以用树形关系来表示,如图所示:
4.0 类与对象概念
5.0 对象的几种创建方式
对象是对类的实例化。对象具有状态和行为,变量用来表明对象的状态,方法表明对象所具有的行为。Java 对象的生命周期包括创建、使用和清除,本次介绍对象的创建,在 Java 语言中创建对象分显式创建与隐含创建两种情况。
5.1 显式创建
对象的显式创建方式有 4 种。
5.1.1 使用new关键字创建
这是常用的创建对象的方法,语法格式如下:
类名 对象名 = new 类名();
5.1.2 newlnstance() 方法
在 Java 中,可以使用反射类的 newlnstance() 实例方法来创建对象,代码格式如下:
java.lang.Class Class 类对象名称 = java.lang.Class.forName(要实例化的类全称);
类名 对象名 = (类名)Class类对象名称.newInstance();
调用 java.lang.Class 类中的 forName() 方法时,需要将要实例化的类的全称(比如 com.mxl.package.Student)作为参数传递过去,然后再调用 java.lang.Class 类对象的 newInstance() 方法创建对象。
5.1.3 调用对象的 clone() 方法
在程序开发中,有时可能好会遇到下列情况:已经存在一个对象A,现在需要一个与对象A完全相同的B对象,并对B对象的值进行修改,但是A对象的原有的属性值不能改变。这时,如果使用java提供的对象赋值语句,当修改B对象值后,A对象的值也会被修改。那么应该如何实现创建一个和对象A完全相同的对象B,而且修改对象B时,对象A的属性值不被改变呢?
public class Test1 {
public static void main(String[] args) {
//业务,我创建一个Student s1 我想用一下s2 其中默认就有s1的值
Student s1 = new Student();
s1.setId(1);
s1.setName("张三");
//定义s2
Student s2 = s1;
//打印他们的内存地址 == 相同的内存地址
System.out.println("s1:"+s1);
System.out.println("s2:"+s2.getName());
//改变一下s2的ID值
s2.setId(2);
//输出一下s1的id
System.out.println(s1.getId());
//总结:因为s2引用的是s1 地址相同,所以s2 改变值 s1 跟随改变。
}
}
要实现这一功能,可以使用Object类中的clone方法。clone方法可以完成对象的克隆实现Cloneable接口。
package com.qst.test;
/**
* @Author: 喝七喜长白白
*/
public class Student implements Cloneable{
private String name;
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
@Override
protected Student clone() throws CloneNotSupportedException {
Student o = (Student)super.clone();
return o;
}
}
测试方法
package com.qst.test;
import java.sql.SQLOutput;
/**
* @Author: 喝七喜长白白
*/
public class Ts01 {
public static void main(String[] args) throws Exception {
Student s1 = new Student("张三");
System.out.println("克隆前:"+s1);
//克隆
Student s2 = s1.clone();
System.out.println("克隆后:"+s2);
//给s2定义新的数据
s2.setName("李四");
System.out.println("克隆更改s2数据:"+s2);
System.out.println("重新打印s1:"+s1);
}
}
5.1.4 调用 java.io.ObjectlnputStream 对象的 readObject() 方法
使用流去创建对象,这里不做具体详解,以上三种常见的创建方式,需要大家牢牢记住,这种方法了解了解即可。
5.2 隐含创建
除了显式创建对象以外,在 Java 程序中还可以隐含地创建对象,例如下面几种情况。
5.2.1 变量定义
String strName = "strValue",其中的“strValue”就是一个 String 对象,由 Java 虚拟机隐含地创建。
5.2.2 字符串的“+”运算符运算的结果为一个新的 String 对象
String str1 = "Hello";
String str2 = "Java";
String str3 = str1+str2; // str3引用一个新的String对象
5.2.3 当 Java 虚拟机加载一个类时,会隐含地创建描述这个类的 Class 实例
类的加载是指把类的 .class 文件中的二进制数据读入内存中,把它存放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class 对象,用来封装类在方法区内的数据结构。