目录
一、面向对象
1.1面向对象的概念
面向过程:在整个事情的执行过程中,自己至始至终都是其中的参与者,并且要自己亲力亲为所有的步骤。
面向对象:我们需要完成某个事情,需要具体的一个结果。这时我们不会自己去参与其中,而是找具备这些功能的对象,然后调用它们的功能,帮助我们来完成我们的要求。
面向过程:
吃饭:
- 先思考吃什么?
- 买菜
- 回家洗菜、烧饭
- 吃饭
- 洗刷
面向对象:
吃饭:
- 先思考吃什么?
- 找饭店
- 找服务员调用服务员的点菜功能
- 服务员会把顾客的点菜信息告诉给大厨
- 大厨把菜做好之后又找服务员,服务员负责上菜
3.吃饭
1.2面向过程和面向对象的差异
面向过程和面向对象都是解决问题的思维方式:
面向过程我们需要参与其中,在整个过程中我们是这个事件的具体的参与者。
面向对象我们不需要参与其中的每个步骤,而只需要我们去找具备对应功能的对象,然后指挥他们做事情即可。
面向对象更加符合现在人们的思维习惯。
1.3对象在需求中的使用和练习
对象在需求中的使用
需求:把大象装冰箱。
一般的做法:遇到需求之后,我们首先分析需求中的名词,基本上需求中的名词就是一个一个的对象(名词提炼法)。
当把名词提炼出来之后,开始分析当前这个对象中具体有哪些行为和功能,或者局部哪些基本的数据。
名词:大象、冰箱。
描述各个名词(对象)的细节:
大象
{ }
冰箱
{ 打开()
{ }
存储( 大象 )
{ }
关闭()
{ }
}
在分析完具体的对象之后,我们需要创建出真实的这些对象。
有大象这个具体真实的事物:
大象 dx = new 对象(); // 创建出了一个大象这个事物
有冰箱这个事物
冰箱 bx = new 冰箱(); // 有了冰箱这个事物
bx.打开(); //打开了冰箱的门
bx.存储( dx ); //把大象装到冰箱中
bx.关闭();
在分析需求的时候,一定要分析清楚当前某个功能或者行为具体应该属于哪个对象上。
对象在需求中的使用练习
人开门:
人:
门: 开属于门自身的功能。
光头强用电锯砍树:
电锯:砍树是电锯的功能。
光头强:使用电锯
一般当我们分析出具体的对象时候,需求中的动作,一般都属于某个对象的功能。
1.4 、对象在代码中的体现
要把生活中存在的具体的个体,以及某个事物最终用Java程序来体现:
生活中的一类事物,可以对应Java中的某个class程序。而把这个class程序称为一个类。因此上述分析的所有的对象,我们都可以使用Java中的类来封装和描述。
当我们需要把生活中的事物使用Java中的类进行封装和描述的时候:
首先需要先分析当前生活中的事物具体基本哪些特点(基本的属性,具备的功能/行为/动作)。然后通过分析再和Java中的类建立对应的关系。最后才能使用Java中的类描述。
人的案例:
我们应该从具体的某个人,或者某几个人中开始分析当前人这一类事物具备的共性特点。
人具备基本的数据:身高、体重、年龄、姓名、性别.......
人具备的基本功能:吃饭、睡觉、学习、打游戏。
人
{
身高
体重
年龄
性别
姓名
吃饭(){}
睡觉(){}
学习(){}
打游戏() {}
}
分析完某一类事物具备的共性特征之后,就要开始考虑这类事物的基本数据使用Java中的什么描述,而事物的基本功能应该使用Java中的什么描述?
事物的基本数据,一般在生活中就是一个数据,这个数据可以使用学习过的一个变量来表示。
事物的行为/功能/动作,可以使用Java中的函数(方法)来描述。
用Java中的类 描述 当前分析的这个事物:事物的名称,就是Java中的类名
class Person
{
double height; //身高
int age; //年龄
char sex; //性别
String name; // 姓名
//描述人这类事物的共性行为
void eat()
{
}
void sleep()
{
}
void study()
{
}
}
当描述完一个事物之后,要在Java程序中使用这个事物,首先需要使用new 关键字创建出这个事物在Java中的对象,然后通过这个对象就可以调用其中的所有特征。
Person p = new Person(); //创建出了一个人 对象
p.age = 23;
p.name = “班长”;
p.sex = ‘男’;
p.eat();
p.sleep();
1.5、对象的内存图解和练习
class Car
{
//车的基本属性
String color;
String name;
String id;
//车的行为
void run()
{
System.out.println("车的颜色:"+ color +",车的品牌:" + name);
}
}
class CarTest
{
public static void main(String[] args)
{
//创建车的对象
Car c = new Car();
System.out.print(c.color);
//给车的属性赋值
c.color = "yellow";
c.name = "BMW";
c.id = "豫B88888";
c.run();
}
}
在程序中使用一个类来描述生活中的某一类事物,而事物的基本属性我们使用了变量描述。这些变量的书写位置和类中的函数属于并列关系。这时这些变量称为类中的成员变量。而类中负责描述行为(功能)的函数称为类中的成员函数(成员方法)。
在类中定义成员变量,和第二天学习的定义变量没有任何区别。只是把变量写在类的成员位置上而已。
类中的成员函数(成员函数),它和我们学习的函数定义完全一致。
在使用Java中的new 关键字创建当前这个类的对象时, 这个类中的所有成员变量,会随着对象在堆中的出现而存在。所有成员变量随着的对象在堆中出现之后,都会有默认的初始化值。
记住:只要在程序中使用new关键字,那么在堆中都会有一个新的对象产生。
1.6、类和对象的区别
要研究类和对象的关系:
为什么要写一个类:Java是通过类这个形式描述生活中的某一类事物。因此我们可以通过类展示生活中的所有事物。
总结:
类和对象的关系:
类是用来描述生活中的某一类事物。而对象是基于这个类在Java中创建出来的真实个体(实例)。
我们可以把类当做生活中某一类事物的共性的总结和描述。
而把Java中的对象可以理解成生活中的具体一个实物。
接下来我们主要学习的任务:
研究如何去描述一个类,以及这个类中能够书写什么内容。
研究基于这个类怎么去创建出Java中的对象,以及创建对象的过程中JVM具体做了什么事情。
研究类和对象之间的关系。
1.7、局部变量和成员变量区别(死不同)
局部变量:定义在函数(函数)中的那些变量。
成员变量:定义在类的成员位置上的变量。
不管是成员变量还是局部变量它们都符合第二天学习的变量的定义规则。
类型 变量名 ;
区别:
在书写代码的时候位置不同:
局部变量需要书写在函数中。成员变量需要书写在类的成员位置上。
它们在内存中的位置不同:
局部变量随着函数的运行会在栈内存中出现。
成员变量会随着对象的出现在堆中存在。
它们的初始化方式不同:
局部变量必须手动的进行初始化,只有初始化之后才能使用。
成员变量可以不用初始化。
它们的生命周期不同:
局部变量是随着函数的进栈在函数所属的栈内存中存在,随着函数的出栈就消失。
成员变量是随着对象的出现在堆中出现。随着对象的消失而消失。
1.8、匿名对象
匿名:没有名字。
1.8.1、匿名对象介绍
class Person
{
String name;
int age;
void sleep()
{
System.out.println("睡觉啦......");
}
void say()
{
System.out.println("name="+name+",age="+age);
}
}
class PersonTest2
{
public static void main(String[] args)
{
Person p = new Person();
p.name = "张三";
p.age = 23;
p.say();
Person p2 = new Person();
p2.sleep();
Person p3 = new Person();
p3.sleep();
}
}
在PersonTest2程序中。
创建的第一个Person对象,目的是要调用其中say函数说出当前这个Person对象的姓名和年龄。因此我们需要给当前的Person对象提供一个p引用,通过这个p引用操作当前这个Person对象的name和age属性。
而在程序中的第二个和第三个Person对象,仅仅只是为了调用sleep函数,而在sleep函数中并没有去访问和这个人本身相关的某些数据。这时对第二个和第三个Person对象起的p2 和 p3 引用变量有些多余。
这时我们就可以想办法省略的p2和p3,然后直接new对象调用函数。
此时直接new 的对象调用函数,这个对象称为匿名对象。
匿名对象的格式:
new 类名().函数名();
new 类名().成员变量; 这种用法没有任何意义。
使用匿名对象调用say函数的时候,打印出来的结果中的name并不是李四。
因为:在使用匿名对象的时候,每次都会new一个新的对象,在使用 new Person().name = “李四”;这句话执行完之后,这个李四是赋值给了当前这个没有名字的一个对象。而在调用say函数的时候,又重新new了一个新的对象,和原来赋值李四的那个Person对象属于2个完全不同的对象。
注意:匿名对象可以简化代码的书写,但是匿名对象一旦使用结束,这时这个对象就立刻变成垃圾。
如果对象只使用一次,这时可以采用匿名对象,如果这个对象要使用多次,必须给对象起名。
1.8.2、匿名对象作为参数传递
class PersonTest3
{
public static void main(String[] args)
{
/*
Person p = new Person();
Person p2 = new Person();
Person p3 = new Person();
Person p4 = new Person();
demo(p);
demo(p2);
demo(p3);
demo(p4);
上述程序中创建的Person对象的引用,仅仅是为了把对象传递给demo函数,
这时也可以使用匿名对象传递对象
*/
demo( new Person() );
}
//定义一个功能,给所有的Person对象name和age进行相同数据的赋值
public static void demo( Person p ) // Person p = new Person();
{
p.name = "baby";
p.age = 1;
p.say();
}
}
1.8.3、值类型和引用类型作为参数传递
//值的传递和引用的传递区别:
class Demo
{
int x ;
void print()
{
System.out.println("x="+x);
}
}
class Test
{
public static void main(String[] args)
{
Demo d = new Demo();
d.x = 10;
show( d.x );
d.print();
/
Demo d2 = new Demo();
d2.x = 10;
show( d2 );
d2.print();
//为什么两次调用 print函数 打印出来的d.x值不同?
}
public static void show( int x )
{
x = x + 100;
}
public static void show( Demo d )
{
d.x = d.x + 100;
}
}
总结:如果在程序中传递的具体的数据,这时在函数中是不会改变对象空间中的数据。
如果传递的是引用,这时通过引用是可以改变对象中的任何数据。