字数:2402
阅读时长:5 min
面向对象思想:对象,实例和实例化(Java表述)
面向对象编程(Object-Oriented Programming)以对象为程序核心,可以实现多态,代码复用性等,是一种能帮助开发人员开发出健壮优秀程序的哲学思想。
Java是一门良好支持面向对象特性的语言,可以说它几乎就是“对象的”,因此详细了解面向对象的意义及特性对于Java开发人员来说极为重要。本文将介绍Java中关于对象和实例的概念。
我在查阅某些资料时,曾被“对象实例化”等概念迷惑,本文也将区分不同的几个概念。
类 Class
类是一种 抽象 的概念,跟它的名字一样,看到“类”应该有“一类东西”这样的感觉。实际在设计上,类就是代表着某一类东西,或者说它是某些对象或物品的抽象。比如,人类就是一个“类”,植物也是一个“类”,流体是一个“类”,它们都是抽象的名词,不是具体的事物,而是对一类事物的逻辑抽象。
这类似于分类,实际上分类对理解类的概念很重要!对每个实际的物品,人们都可以想出一个它属于的类型,然后把它归于其中。假设某人创造了世界上独一无二的变异大蟑螂,尽管只有一只,它仍然有自己的类,即“变异大蟑螂类”(随这个发明者自己起名字)。
那么为什么能把这一类东西抽象出来呢?这是因为这些东西都具有相同的某些特征,人都是高级灵长类动物,有两个眼睛两只手,发达的大脑等等。这些都是人类的特征,我们叫做“类的属性”。它们也可以做一些事,人也可以跑步,也可以制作某些东西和使用东西,会说出一段话等等,这些都是人类的行为,我们叫做“类的行为”。
在面向对象的程序设计中,我们把类具有的属性称作 "Field"(域,字段或成员变量),把类的行为称作 "Method"(类的方法,某些语言可能称作函数)。在程序中定义一个类,需要指定类的名称,它具有的属性和方法(是什么,可以做什么)。
// 为了便于讲述,下面的程序省略了很多细节
// 如:修饰符,构造器等
class MyClass {
// 这里定义了类的域
int a_number;
int b_number;
// 这里定义了类的方法
void give_number(int a_num, int b_num) {
a_number = a;
b_number = b;
}
void do_something() {
//do something here!
}
}
在定义完类之后,你的程序就可以使用它,就像你使用 int 一样:可以定义一个int的变量,你也可以弄出一个 MyClass 的变量,应该说是MyClass类的一个对象。
对象 Object
对象(Object),按照原意其实应该翻译为“东西”,这特指那些存在的事物。对象与类是对应的,比如张三是人类,Tom是猫类,电脑是电子产品类,拖鞋是衣物类一样。如果我们要弄出一个属于MyClass类的对象,那么这个对象就是MyClass类(废话)。
Java中要创造一个类的对象,需要使用 new 关键字。JVM遇到 new 时将会进行类加载,空间分配,自动初始化域等一系列过程,在这里我们只需要知道,new 相当于在你的程序世界中腾出了一块空间,在这块刚刚合适的空间上创造了某一类的对象。
// 不讨论使用反射、代理、反序列化等一系列创造对象的技术
// 我们用最一般,最正常的方式
// new了一个MyClass类的对象并让它调用方法做一些行为
new MyClass().do_something();
// new了一个MyClass类的对象
// 并用MyClass类型的变量myClass代表这个对象
// 然后通过myClass变量调用方法做一些行为
MyClass myClass = new MyClass();
myClass.do_something();
正如前面说的,类其实可以看做是分类,很自然而然地会出现“子类”的现象,子类是具有父类(子类-父类,派生类-超类,有一系列叫法表示相同含义)的属性的,比如人类肯定具有动物的属性,可以做出同样的行为(取决于你会不会做)。注意,不要拿某人和某鱼比较,因为鱼也是动物的子类,鱼并不代表动物,它和人是动物的两个分支,这里的动物是具有所有动物都有的属性的,比如会自己动,具体参见生物分类学。
面向对象编程中也有类似的概念,即继承,子类会继承父类的所有域和方法。
class YourClass extends MyClass{
int c_number;
void give_c(int num) {
c_number = num;
}
}
现在YourClass继承了MyClass,它的效果看上去就跟下面这样一样(只是为了说明MyClass也具有这些域和方法,实际上完全不是!)
class YourClass extends MyClass{
int a_number;
int b_number;
int c_number;
void give_c(int num) {
c_number = num;
}
void give_number(int a_num, int b_num) {
a_number = a;
b_number = b;
}
void do_something() {
//do something here!
}
}
实例 Instance 和实例化
我阅读了一些网上的中文文章,发现了一些奇怪的词语,比如“对象实例化”这个词,并产生了一些误解,这里再详细介绍一遍。
Instance 就是例子的意思,这里译为实例没有任何不妥。它是对于对象而言的,比如人类,假设你在向外星人介绍人类,它们要求你举一个例子,你说张三就是个例子!现在把名词换过来,即张三这个人是人类的一个实例!而通过对象与类的概念可以知道,张三也是人类的一个对象!所以说,某个类的实例就是这个类的对象,那么我们创建某个类的对象的过程,就说成是创建这个类的实例。其实它们有一个很重要的区别,看下一个小标题!
MyClass myClass2 = new MyClass();
YourClass yourClass2 = new YourClass();
上述代码可以说成创建了这两个类的对象,也可以说成进行了这两个类的实例化,所以确切来说,应该讲成“类实例化”而不是“对象实例化”。
实例和对象的重要区别
在我们的表述中,对象这个词是很严格的,它和类是严格对应的关系,张三是人类的对象这点是绝对的,myClass2 对象是 MyClass类的对象这点也是绝对的,yourClass2 对象更是 YourClass类的对象,再没有别的关系。
等等?!YourClass类是MyCLass类的子类啊,那么yourClass2为什么不能是MyClass类的对象呢(这里可能有点晕,注意看好对象和类这几个字)?
因为 继承,它们的区别才显现出来。
要知道,对象关系,比实例关系更严格。用什么类,就会创造出什么类的对象,这是严格的“ 是” 和“一一对应”的关系。
而实例,就跟它的意思“例子”一样,要宽容很多。注意看这张图!
这张图中,我们把丁香和迎春花看做是两个具体的对象(实际不是这样的,假设你面前存在这两朵花就行),丁香就是丁香属类的对象,迎春花就是茉莉属类的对象。如果我让你分别举一个丁香属类和茉莉属类的例子,你肯定会毫不犹豫地说出丁香和迎春花。但现在,如果我让你举一个木犀科类的例子呢,没错,丁香和迎春花就是木犀科类的例子!就像我让你举一个动物的例子,你会说出某人张三,某王八李四,某河豚王五等等,不管它们怎么样,反正都是动物!
其实, 实例 和 对象 的区别就是“举例子的分类” 和 “实际就是的对应” 的区别。
在Java中,我们可以通过以下代码实际反应出来
// 先实例化两个类的两个对象
MyClass myClass3 = new MyClass();
YourClass yourClass3 = new YourClass();
boolean a = myClass3.getClass() == yourClass3.getClass();
boolean b = myClass3 instanceOf MyClass;
boolean c = myClass3 instanceOf YourClass;
boolean d = yourClass3 instanceOf YourClass;
boolean e = yourClass3 instanceOf MyClass;
// a, b, c, d, e 的值分别为
// false, true, false, true, true
因为 YourClass 类是 MyClass 类的子类,就跟上面分类的例子一样, yourClass3 这个对象即是 MyClass 类的实例,又是 YourClass 类的实例,但它始终只是 YourClass 类的对象。
完。
网友评论