面向对象思想
最近一直在搞javascript,在搞的时候也没有想过真正的去了解语言这个东西,学到最后越来越迷茫,分析原因,是面向对象没搞清楚,然后就去找了Java来学习,当然了只是学了个基础,没有深入。Java课程里面向对象的介绍会更多些。
下面我们就一起学习面向对象编程,只要你是想学习javascript的也就该认真的把下面的内容看完。
编程语言的发展都是朝着人类更容易理解的方向前进,所以就有了我们今天的面向对象编程。
那么什么是面向对象语言呢?下面以它和面向过程语言做个对比。
面向过程语言:你要了解每个对象在执行过程的中间里的每一个细节。
面向对象语言:你就不用去了解过程,你只需用对象即可。
比如我们的javascript,严格来说它不算面向对象语言,因为面向对象里重要的概念 类(class)javascript是没有了的。它仅仅只是基于对象的一门语言,编程的时候有点面向对象的味道。
这里有个例子:
比如:我要打一篇文章。
如果我用面向过程的设计思想来封装这件事那么我就该这样说:我开机,我打开文档,我在键盘上打字,好了,我打完了一篇文章。
面向过程一切以你问中心,所有的每个细节你都要清清楚楚,当然了在这过程中你可以把怎么打开电脑,怎么在键盘上打字的都封装为一个个的函数,你只要调用即可。但是这里的每个方法内部是怎么运作的你都必须一一了解,因为是面向过程。
如果是面向对象设计思想我就该这样说,电脑write(写)我要一篇文章,你下达命令,电脑帮你把文章写好了,具体是怎么写的你不用知道,你要得到你的结果(一篇文章),其他的细节交给电脑即可。
总结:
面向过程和面向对象的区别
主要是在复用的层面上来讲的,面向过程主要在方法的层面复用(得到结果每个步骤你都该知道)而面向对象就是把方法和相关细节都隐藏了,给你直接在对象的层面上复用(得到结果每个步骤你不必知道)
面向对象中最重要的思想就是,把合适的方法放在合适的类里面,方法该放哪就见仁见智了。
现在不知道什么是类没有关系,下面我们再来细说,学过javascript基础的同学都该知道,javascript中是没有类的概念的,类在javascript中可以直接看成是对象,Java中是类创建对象,那么javascript中就是对象中创建对象,javascript一切皆对象。
既然现在大家都了解什么是面向对象思想了,那么以后在我们写程序中的时候,就不该这样来思考问题了,比如对于这个问题,我第一步该怎么做,第二步该怎么做,这样就是面向过程的编程思想了。要用面向对象的思想来思考问题我们该这样想,遇到一个问题,我们先要分析,这个问题里面该有什么类(对象)?类会生出什么对象?类和生出的对象该有什么方法和属性?类和类之间都有什么关系?
现在举个javascript中经常遇到的问题:
比如我们要用到javascript中的BOM对象(不知道BOM的同学,请翻阅文章javascript知识总汇)
那么我们就要分析,BOM对象中都有什么属性?什么方法?它里都有什么子对象给我们提供呢?子对象都有什么属性什么方法?
在用javascript操作的时候,里面都给我们提供了很多内置对象,基本很少需要自己再定义了,如果有需要的话,就按照上面分析的来创建对象即可,思想很重要,有思想就不至于走路茫茫然。
总结:
遇到一个问题时候:先要抽象出类----类该有的方法和属性(如果某个方法和属性对于我们的业务系统来说是没有任何关系的话就不必封装了)---派生出来的对象。
官方点的说法
面向对象的设计思想:
面向对象的基本思想是,从现实世界中客观存在的事物出发来构造软件系统,并在系统的构造中尽可能运用人类的自然思维方式。
面向对象更加强调运用人类在日常的思维逻辑中经常采用的思想方法和原则,如抽象,分类,继承,聚合,多态等。
类:
用来描叙同一类型的对象的一个抽象的概念,类中定义了这一类对象所有具有的静态和动态属性。
对象:
某个类具体的某一个对象。
类可以看成是一类对象的模板,它抽象出对象该有的方法和属性,对象看成该类的一个具体事例。
根据这个类可以延伸出不同的对象。这些具体的对象都拥有这个类的一套属性,只是取值不同,依据属性值不同来区分不同的对象。至于类的方法,所有该类衍生出来的对象都共有这个类方法,只是具体的调用方式不同,比如调用一个类里面的一个有参数的方法,不同的对象都有可能传入不同的参数。举个现实中的例子,同样是调用跑的方法,有的人腿长一点那么就跑的快一些,有的短就跑的慢些。
类之间的关系:
这里对于我们学习javascript没有多大的关系,只需了解即可。
1关联关系: 一个类的方法是另一个类的具体的某个对象,我的方法的参数是你这个类的一个对象。
2继承关系:XX是XX的一种,猫是动物的一种,猫就从动物继承,狗也是动物的一种,所以狗也从动物中继承。继承很有可能会产生一颗继承树。
某个类可能从多个类中继承。猫是动物的一种,猫从动物中继承
3聚合关系:一个整体和部分的关系。xx是xx的一部分。关系不紧密,没有谁离不开谁,
4组合关系:一个整体和部分的关系。xx是xx的一部分。关系紧密,互相密不可分。
5实现关系:一个类的方法,不同的对象都有自己对该方法的一个实现方法。
为什么用面向对象?
更好的 复用,面向过程属性和方法是分开的不是聚合的关系,复用局限在方法。面向对象把属性和方法综合在一起,复用时候是整个对象复用。
构造方法:
用法:把自己构造成一个对象,new+构造方法=创建一个新对象,
构造方法用来初始化对象的函数,构造方法与类同名且没有返回值。
public class Student{
int id;
int age=20;
student(int a ,int b){
id=a;
age=b;
}
}
创建对象:
Student stu=new Student(1,25);
当定义类的时候没有指定构造函数,那么编译器为类自动添加形如 -------类名(){}的构造函数。
如下面的类没有构造函数
class po{
int x;
int y;
po(){}默认添加,x和y初始为0;如果你自己定义了构造方法那么系统就不会给你添加这形式的构造方法了。当然自己定义了两个构造方法也是可以,创建对象的时候可以根据参数的不同调用不同的构造方法---方法重载。
}
创建对象:
po m=new po();
方法重载overLoad
(一个类中可以定义有相同的名字,但参数(个数,类型)不同的多个方法。调用时,会根据不同的参数选择对应的方法,只要这些方法在调用的时候编译器能区分开来不会造成混淆,就构成重载);
比如javascript中的date对象可以通过不同构造方法创建:
new date();没有参数的时候对象的时间是客户机系统时间。
new date(参数);参数的时间
对象的使用:
必须使用new关键字创建对象;
使用对象引用.成员变量来引用对象的成员变量;
使用对象引用.方法(参数)来调用对象的方法;
同一个类的每个对象有不同的成员变量存储空间‘
同一类的每个对象共享该类的方法。不是自己对象里单独存一份。不同的对象执行方法的过程是不一样的。腿长的跑的快,短的慢,依赖自己的属性。
非静态方法是针对每个对象进行调用,就是说你要调用该方法,就必须先new(创建)出一个对象,然后对象名.方法名来调用。
区别:
javascriptstring对象和math对象。
string对象必须创建对象才能使用string对象中的属性方法,javascript是比较智能的一门语言,如果它能自己分辨方法和属性的对象,那么就不用创建该对象,如基础类型number,string....
math对象不用创建直接通过类名.调用属性和方法。前面说过javascript中没有类的概念,类在javascript叫对象。
内存分析
在内存中区分类和对象:
类是静态的概念,位于代码区。
对象时new出来的,位于堆内存,类的每个成员变量在不同的对象中都有不同的值(除了静态变量——而方法只有一份,执行的时候才占内存。同一个类的每个对象有不同的成员变量存储空间。同一个类的每个对象共享该类的方法。
堆内存:动态分配内存。
形参和局部变量同等对待。
方法返回值存在临时区域里。
方法只有在执行的时候才占用内存,方法一旦调用完毕所有与该方法相关的局部变量都会消失。
弄清内存就弄清了一切。
写方法时要确定三个问题:
方法名:要考虑别人怎么用。
方法参数:
方法返回值:
如:为一个cricle类添加一个方法,计算一个点(point对象)是否在圆(cricle对象)内。
分析
方法名:
考虑别人是怎么用你的方法,
xx.包含()圆?
包含===命名为contains(s第三人称)
参数===包不包含某个点?我要传递一个点来问你包不包含,所以参数就是一个点对象。
contains(point p);
是否包含:包不包含 是后否===布尔值。
boolean contains(Point p){
....
if(...){
....
return false;
}else{
....
return true;
}
}
this 关键字:
在类方法定义中使用的this关键字代表的是使用该方法的对象的引用。
当必须指出当前使用方法的对象时谁时就要使用this;
有时候使用this是为了处理方法中成员变量和参数重名的情况;
this可以看做是一个变量,它的值是当前对象的引用。
总结:
this一般出现在类的方法的定义里面,你在对哪个对象调用该方法,this指的就是这个对象,在定义的时候this指的是谁,它并不知道,this是一个引用,它指的是自身的对象。
当你的一个参数不确定是你指定的哪个声明的变量时,找离它最近的声明,就近声明。
public class leaf{
int i =0;
leaf (int i){
this i=i; 左边的i有this就可以确定是成员变量的i,右边的i找最近的i就是形参中的i
}
}
最后,说下学习方式:
重新敲代码的时候,不要照着代码来敲,是要想着思路来敲,思路忘了再看资料,想想自己思路卡在哪里了,慢慢多看多练,你的思路慢慢就培养了。就像写作文一样,先看人家的作文,先学会认字,学基础规则,构成词,构成句子,然后再来谈写作文,不要焦急,慢慢来,把基础都打好。