面向对象思想
前言
计算机的革命起源于机器,所以说,编程语言的产生也是始于对机器的模仿。在19世纪的早期就已经出现过计算机的雏形。那时,人们为了构建导航所需的表格对计算机产生了需求。于是有一个叫做"查尔斯巴贝奇"的人在英格兰就设计了一台叫做差分机的计算装置。它能够自动地计算构造出数学表所需的多项式的值。
遗憾的是,巴贝奇最后并没有完成它的差分机,差分机后来在1855年由Per Georg Scheutz在瑞典制造
而巴贝奇设计的机器叫做分析机,在1871年巴贝奇去世之前,他也只来得及做出其中的一部分以测试他的概念是否可行。分析机是一个完全的机械装置,拥有完成计算的处理单元,输入输出数据的手段,以及一个穿孔木片的存储器能够保存数据和程序。
巴贝奇的计算器
巴贝奇的分析机
巴贝奇分析机在计算机发展史上有着非常重要的地位,一些早期的计算机先驱都受到了巴贝奇工作的启迪甚至有人认为,巴贝奇的分析机比20实际40年代的早期电子计算机更先进,更接近现代的计算机
"奥古斯塔 阿达 金"是一位英国作家,数学家,她也曾与巴贝奇一起制作分析机。1842年她翻译了意大利数学家"路易吉
蒙博"所撰写的关于分析机的备忘录。作为工作的一部分,她重写了包括用分析机计算伯努利数的一系列注释。由于这一工作,阿达被认为是编写计算机程序的第一人。阿达之后经过了大约一百年的技术进步,人类才能真正地编写和运行程序。
计算机程序
计算机上执行的代码表示为二进制 1 和 0
组成的串,它被称作机器码。每种计算机它都只能执行一种特定的机器码。人类可读的机器码就比如ADD,R0,Time这种叫做汇编语言。能够在类型完全不同的计算机上运行。与底层计算机体系结构几乎没有关系的代码叫做高级语言,比如C语言,C++语言,Java语言等。在执行之前,高级语言程序必须首先被编译成计算机的本地机器码。
面向过程语言
面向过程和面向对象都是对软件分析、设计和开发的一种思想,它指导着人们以不同的方式去分析、设计和开发软件。
早期最具有代表性的面向过程语言如C语言、Fortran语言
C语言的运用非常之多,它兼顾了高级语言和汇编语言的优点,相较于其它编程语言具有较大优势。计算机系统设计以及应用程序编写是C语言应用的两大领域。同时,C语言的普适较强,在许多计算机操作系统中都能够得到适用,且效率显著。
Fortran语言的最大特性是接近数学公式的自然描述,在计算机里具有很高的执行效率。易学,语法严谨。可以直接对矩阵和复数进行运算,这一点类似matlab。自诞生以来广泛地应用于数值计算领域,积累了大量高效而可靠的源程序。很多专用的大型数值运算计算机针对Fortran做了优化。广泛地应用于并行计算和高性能计算领域。Fortran90,Fortran95,Fortran2003的相继推出使Fortran语言具备了现代高级编程语言的一些特性。
面向过程的思想
面向过程的思想就好比假如我要买一个笔记本电脑来打游戏,那么我们的步骤就是取钱,走到店里,把钱交给老板,然后把电脑带回家下载游戏即可。但是假如我要造一台笔记本电脑来玩游戏,那么使用面向过程的思想就有点不太合适了。因为造一台笔记本电脑需要很多很多的配件,一个一个列出来是很复杂的,因此面向对象的思想就诞生了~
面向对象思想
面向对象的思想更契合人的思维模式,我们需要思考的是,笔记本是由哪些配件组成,然后我们就会根据需要的那些配件来找到专门制作的厂商进行购买或者自行研发来组成一个笔记本电脑。
访问权限控制
在Java语言中提供了访问权限修饰词,以供类库开发人员向客户端程序员指明哪些是可用,哪些是不可用。访问权限的控制等级从最大权限到最小权限的顺序依次为
public int A; //所有类都可以访问 protected int B; //子类可以直接访问 int C; //同一个包下,对象可以访问
private int D; //任何情况下外界都无法访问
初始化和清理
初始化和清理是设计安全的两个问题,许多C语言出现的错误都是程序员忘记初始化变量。清理也是一个特殊的问题,当使用完一个元素的时候,程序员很容易把它忘记,这样一来,这个元素占用的资源就会一直得不到释放,结果就是资源用尽。
在C++里面提供了构造器的概念,这是一个在创建对象时自动调用的方法,Java也提供了这个概念,并且还额外提供了垃圾回收器。对于不再使用的资源,垃圾回收器会将其释放。
虽然Java有垃圾回收器负责回收无用对象占据的内存资源,但是也有特殊情况。假如你的对象获得了一块特殊的内存区域,由于垃圾回收器只知道分配那些由new分配的内存,所以它不知道该如何释放这块特殊的内存,为了应付这种情况,Java允许在类中定义一个名为finalize()的方法。它的工作机制就是一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()的方法,并且在下一次垃圾回收的动作发生时,才会真正回收对象占用的内存。所以使用finalize(),就能在垃圾回收时刻做一些重要的清理工作。
但是有一点需要注意。不要把finalize()当成是C++里面的析构函数。在C++里面,对象最终一定会被销毁,而在Java中的对象却并不一定每次都会被回收。所以得出的总结是,对象不一定会被垃圾回收,垃圾回收也不等于析构函数~
在C++中,所有的对象都会被销毁,或者说应该会被销毁。如果在C++中创建了一个局部对象(也就是在堆栈上创建),这个时候对象的销毁动作就会发生在此对象作用域的末尾处。如果对象是用new创建的,那么当
程序员使用C++调用delete操作时,就会调用响应的析构函数。如果程序员忘记调用delete,那么就永远不会调用析构函数。这样就会出现内存的泄露,对象的其他部分也不会得到清理。这种缺陷也很难跟踪。
而在java里面呢,是不允许创建局部对象的。在Java中也没有用于释放对象的delete,或者free。因为垃圾回收器会帮助你释放存储空间。由于垃圾处理机制的存在使得Java没有析构函数。然而随者学习的深入就会慢慢明白,垃圾回收器的存在并不能完全替代析构函数。如果希望进行释放存储空间之外的清理工作,还是得明确调用恰当的某个Java方法,这就类似于析构函数了,只是没有那么方便~
继承
Object类是所有Java类的根基类,也就意味着所有的Java对象都拥有Object类的属性和方法。如果在类的声明中未使用extends关键字指明其父类,则默认继承Object类。
Object类中的方法
boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
Class<?> getClass() 返回此 Object 的运行时类。
int hashCode() 返回该对象的哈希码值。
void notify() 唤醒在此对象监视器上等待的单个线程。
void notifyAll() 唤醒在此对象监视器上等待的所有线程。
String toString() 返回该对象的字符串表示。
void wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
void wait(long timeout) 在其他线程调用此对象的 notify() 方法或 notifyAll()
方法,或者超过指定的时间量前,导致当前线程等待。
void wait(long timeout, int nanos) 在其他线程调用此对象的 notify() 方法或 notifyAll()
方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
protected Object clone()创建并返回此对象的一个副本。
protected void finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
super关键字
super“可以看做”是直接父类对象的引用。每一个子类对象都会有一个super引用指向其直接父类对象。
class Parent{ public static String color; public void getColor() { System.out.
println("color = " + color); } } public class Test extends Parent{ public void
function() { super.color = "red"; super.getColor(); } }
多态
多态指的是同一个方法调用,由于对象不同可能会有不同的行为。多态是方法的多态,不是属性的多态。多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。
class Language{ public Language() { } public void talk() { System.out.println(
"人类用语言交流"); } } class Chinese extends Language{ //重写了父类方法 public void talk() {
System.out.println("中国人用汉语交流"); } } class English extends Language{ //重写了父类方法
public void talk() { System.out.println("英国人用英语交流"); } } public class
ProjectTest{ public static void main(String[] args) { //现在我们直接new Language对象
Language language= new Language(); language.talk(); //多态,父类可以直接new子类 Language
chinese= new Chinese(); chinese.talk(); Language english = new English();
english.talk(); } }
抽象类
使用abstract修饰的类。通过abstract方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。而使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。
普通的方法可以在抽象类里面实现,但是抽象方法,在抽象类里面只可以声明,然后必须在子类里面实现。
abstract class Test{ public void method() { System.out.println("我是抽象类中的普通方法");
} public abstract void function(); } public class ProjectTest extends Test{
@Override public void function() { System.out.println("我是实现抽象类声明的方法"); } }
接口
接口关键字使得抽象的概念又更近了一步,interface定义的变量仅仅只是声明,完全靠子类实现。接口更多的是用来建立类与类之间的协议,是一种标准。接口中的方法类型默认为public,并且也无法声明成其他访问权限。写不写都是public。
interface A{ void function(); } public class ProjectTest implements A{
@Override public void function() { System.out.println("我是实现接口声明的方法"); } }
内部类
在Java中,我们可以把一个类定义在另一个类的内部,称之为内部类。作为类的成员存在,和成员变量、成员方法、构造方法、代码块并列。因为是类的成员,所以非静态成员内部类可以使用public、protected
、默认、private修饰,而外部类只能使用public、默认修饰。
内部类可以直接访问外部类的成员。外部类不能直接访问内部类的成员,需要先创建对象再通过对象名访问
内部类提供了更小的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问。内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。
但外部类不能访问内部类的内部属性。接口只是解决了多重继承的部分问题,而内部类使得多重继承的解决方案变得更加完整。用匿名内部类实现回调功能。我们用通俗讲解就是说在Java中,通常就是编写一个接口,然后你来实现这个接口,然后把这个接口的一个对象作以参数的形式传到另一个程序方法中,
然后通过接口调用你的方法,匿名内部类就可以很好的展现了这一种回调功能
public class ProjectTest{ class inside{ } }