划重点~面向对象。要进入主题啦。
01-面向对象(概述)
面向对象是一种思想。
早期的思想是面向过程,思想有一个演变形式,慢慢演变成了面向对象。面向对象是相对于面向过程而言的。
通过一个例子来说明:
把大象放进冰箱里。
步骤:
1,打开冰箱门。
2,把大象放进去。
3,关上冰箱门。
我们在强调过程。这个是一个标准的面向过程的思想,注重的是这个过程中的行为。
既然打开、存放、关闭,都是冰箱的行为,我们就把这些行为全部定义到冰箱中,让冰箱来完成。冰箱是一个实实在在存在的东西,我们把它叫做对象。
面向对象,将复杂的问题变得简单了。以前要考虑那么多步骤,现在考虑一个对象就好啦。我们的角色也发生了变化,从以前的执行者变成了现在的指挥者。
虽然现在有了面向对象,但面向过程还是存在的,它的存在是有道理的。面向过程是面向对象的基础。
02-面向对象(举例)
买电脑
面向过程:去买之前会在网上做很多功课,了解什么CPU好、什么显卡好之类的。
面向对象:找一个懂行的朋友,帮你去判断 、帮你去砍价,你只需要最后付钱。这个过程你不需要了解其中什么硬件好,不用你自己去做,只要执行朋友的判断功能、朋友的砍价功能就好。
从执行者变成指挥者。
软件公司
老板就是用面向对象的思想来思考问题,他在寻找具有编程能力的人来完成编程的任务,而不是自己亲力亲为编所有的代码。
而求职者就是那个对象。老板指挥员工做事情,老板在使用员工所具有的编程功能,为公司创造价值。
餐厅
服务员、厨师、收银员等等,都是对象,具有各自的功能。
当然,对象不单单指人。在Java中,万物皆对象。我们可以把现实生活中所有东西看做一个对象。
面向对象可以让复杂的问题简单化。
让我们从执行者变成指挥者。
写程序的时候,不是先定义功能,而是先找对象。(买电脑不是先去查什么硬件好,而是直接找一个懂的人)
在开发的时候,先看Java是不是已经提供了相应的对象,如果有,直接拿来用。
如果没有对象,就造一个对象,然后把需要的功能定义到里面去。(软件公司没有招聘到具有Java开发能力的员工,就在公司内部进行培养,培养出一个可以进行Java开发的人)
03-面向对象(类与对象的关系)
人开门:名次提炼法。
人
{
开门(门)
{
门.开();
}
}
门
{
开(){操作门轴等。}
}
面向对象的三个特征:
封装,继承,多态。
以后开发:其实就是找对象使用。没有对象,就创建一个对象。
找对象,建立对象,使用对象。维护对象的关系。
类和对象的关系:
类:对现实生活中事物的描述。
对象:就是这类事物,实实在在存在的个体。
例:
现实生活中的对象:张三 李四。
想要描述:提取对象中的共性内容。对具体的抽象。
描述时:这些对象的共性有:姓名,年龄,性别,学习Java的功能。
这个描述是用class定义的类来体现的,对象是在Java操作中通过new操作符来产生的实体,这个实体在堆内存当中。
因此,把这些东西映射到内存中,一个是类,一个是实体。
例:
//需求:描述汽车(颜色,轮胎数)。描述事物其实就是在描述事物的属性和行为。
//属性对应是类中的变量,行为对应的是类中的函数(方法)。
//其实定义类,就是在描述事物,就是在定义属性和行为。属性和行为共同成为类中的成员(成员变量和成员方法)。
class Car
{
//描述颜色
String color="红色";
//描述轮胎数
int num=4;
//运行行为
void run()
{
System.out.println(color+".."+num);
}
}
class CarDemo
{
public static void main(String[] args)
{
//生产汽车。在java中通过new操作符来完成。
//其实就是在堆内存产生一个实体。
//new Car();这个汽车为了方便操作,得给它取一个名字,就叫c吧
Car c=new Car();//c就是一个类类型变量。记住:类类型变量指向对象。
//需求:将已有的车的颜色改成蓝色。指挥该对象做使用。在java中指挥方式是:对象.对象成员
c.color="blue";
c.run();
Car c1=new Car();
c1.run();
}
}
多个引用指向同一个对象:
04-面向对象(成员变量和局部变量)
如果需要运行,则写上主函数,如果不需要运行,只是简单描述事物,就不用写主函数啦。
而且可以定义多个类,需要一个主函数就好啦,在一个主函数中可以声明各种对象,并调用它里面的东西~
成员变量和局部变量
作用范围:
成员变量作用于整个类中。
局部变量作用于函数中,或者语句中。
在内存中的位置:
成员变量:在堆内存中,因为对象的存在,才在内存中存在。
局部变量:存在栈内存中。
也可以在本类中写主函数,这主函数中可以创建本类的对象。这个叫在本类中创建本类对象。
这样写不可以哦,语法上是不允许的。主函数前面带static,run()前面没有,要访问它也得加上static。
至于static是什么意思呢,接着看~后面很快就会说到。
但一般程序不会把主函数写在类中,因为一个程序有n多个类,需要一个入口就行啦,不需要多个入口。
05-面向对象(匿名对象的应用)
接下来说一个小知识点,叫匿名对象。就是没有名字的对象。
不起名字,就是对象的一种简写格式。这种格式有它的应用场景,也有它的弊端。
Car.c=new Car();
c.num=5;
这两句话可以简写成一句话:
new Car().num=5;
匿名对象调用属性是没有意义的,因为当前语句执行完之后这个对象就会消失。
而匿名对象调用方法是有意义的,因为方法会执行出来,它是有运行内容在里面的。
匿名对象使用方式一:当对对象的方法只调用一次时,可以用匿名对象来完成,这样比较简化。
如果对一个对象进行多个成员调用,必须给这个对象起个名字。
匿名对象使用方式二:可以将匿名对象作为实际参数进行传递。
//需求:汽车修配厂。对汽车进行改装,将来的车改成黑车,三个轮胎。
main()
{
Car c=new Car();
show(c);
}
public static void show(Car c)
{
c.num=3;
c.color="black";
c.run();
}
还有一种方法,在main函数中直接:
show(new Car());
这样可以提高效率~
用第一种方法,运行结束之后想要释放空间,让堆内存中的数据变成垃圾,可以在main函数中加一句:
c=null;
06-面向对象(封装概述)
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
意思就是我们不需要知道实现细节,只要会用就行啦。
比如买电脑直接找一个懂行的人,不用懂什么硬件好,不用懂怎么去砍价,直接从他这里拿到一个现成的电脑就OK。
好处:
将变化隔离。修改其中某一部分对其他不影响,整体依然发挥它的作用。
便于使用。不用了解原理。
提高重用性。可以重复使用。
提高安全性。不必要了解细节,就是提高安全性。(你自己都不懂,还亲自上手胡捣鼓,肯定有安全隐患)
封装原则:
将不需要对外提供的内容都隐藏起来。
把属性都隐藏,提供公共方法对其访问。(就像连接主机的线~)
类---->包---->框架。
框架是一个集成性相当好的工具,它可以帮你实现很多功能组件的开发。你不需要了解细节,直接拿过来按它的说明来使用就OK啦。
07-面向对象(封装private)
private:私有,权限修饰符:用于修饰类中的成员(成员变量,成员函数)。
私有只在本类中有效。
将age私有化以后,类以外即使建立了对象,也不能直接访问。
但是人应该有年龄,就需要在Person类中提供对应访问age的方式。
但是名字叫haha太不规范了。
一个类中通常有很多属性,每个属性一般对应两个方法:设置(set)和获取(get)。
注意:私有仅仅是封装的一种表现形式。
其实不私有,也可以实现封装。私有是封装的最小权限。
之所以对外提供访问方式,就是因为可以再访问方式中加入逻辑判断等语句。
对访问的数据进行操作。提高代码健壮性。
如果不私有,外界直接可以访问,就不能保证外界设置数据是否合理了。
注意:
1,凡是set打头的方法,返回值类型是void。
2,凡是get大头的方法,返回值类型和它获取的变量一致。
3,凡是看到有一对方法:set***和get***,那么这个类中一定有一个私有的成员变量***。
08-面向对象(构造函数)
构造函数的特点:
1,函数名与类名相同。
2,不用定义返回值类型。和void不一样。void是没有一种具体的返回值类型,而它是根本不需要定义返回值类型。
3,不可以写return语句。返回值类型都没有,所以这个函数中是不会出现return语句的。你不写,系统也不会加。
对象一建立就会调用与之对应的构造函数。
构造函数的作用:可以用于给对象进行初始化。
有一个小问题,刚刚写的类也没有这个函数呀,那它怎么初始化的呢?
当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。
大概酱紫,是为了方便进行初始化,否则没有办法初始化。
当在类中自定义了构造函数后,默认的构造函数就没有了,系统就不会帮你加啦。
一个类中可以有多个构造函数,构造函数可以有重载。我们定义不同的构造函数,对不同的对象进行初始化。
这样结果会是什么呢?
会出错哦。
这样的情况这个对象是无法建立的。
构造函数和一般函数除了在写法上有不同。在运行上也有不同。
构造函数是在对象一建立就运行。给对象初始化。
而一般方法是对象调用才执行,是给对象添加对象具备的功能。
一个对象建立,构造函数只运行一次。
而一般方法可以被该对象调用多次。
有了构造函数,“孩子”一出生就有名字了,那还需要setName这种函数吗?
需要的。
构造函数只是在对象建立的时候运行一次,而后面想要修改名字,需要用到setName这个函数。
什么时候定义构造函数呢?
当分析事物时,该事物存在具备一些特性或行为,那么将这些内容定义在构造函数中。
09-面向对象(构造代码块)
构造代码块的作用:
给对象进行初始化。
对象一建立就运行,而且优先于构造函数执行。
和构造函数的区别:
构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。
比如每个“孩子”出生都会哭,就可以把这个功能放在构造代码块中,不用再在每个构造函数中都写哭这个功能了。
构造代码块中定义的是不同对象共性的初始化内容。
10-面向对象(this关键字)
构造函数可以私有化。
但是如果把一个类中所有构造函数都私有化,代表着这个类无法创建对象。
一个问题:如果构造函数中,形参和属性同名,该怎么区分它们呢?
为了区分局部变量和成员变量,这个时候就需要给成员变量加一个标记。
this:看上去,是用于区分局部变量和成员变量同名情况。
this:为什么可以解决这个问题呢?
this到底代表的是什么呢?
this:就代表本类的对象。到底代表哪一个呢?
this代表它所在函数所属对象的引用。
简单说:那个对象在调用this所在的函数,this就代表哪个对象。
当然正式写的时候还是要写成this的。
其实这些位置都是有this的:
p调用的函数,this就代表p,p1调用的函数,this就代表p1。
那些this之前都被省略了。在没有同名情况的时候,都可以省略的。但是出现变量同名情况,就一定要加。
11-面向对象(this关键字的应用)
this的应用:当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。
但凡本类功能内部使用了本类对象,都用this表示。
12-面向对象(this关键字在构造函数间调用)
this:可以用于构造函数之间互相调用。
有些时候会出现这种情况,构造函数有很多,对外提供的却只有一个。这个时候内部就可以互相调用实现很多初始化功能。
this语句只能定义在构造函数的第一行,因为初始化要先执行。