目录
1.什么是面向对象(oop)
我们学过的C是属于面向过程的程序设计语言,注重于过程的完成分别需要哪些步骤,
例如:洗衣服,需要拿个盆——放水——把衣服放盆里——倒入洗衣粉——揉搓——把衣服拧干拿出来——倒掉水——再放水——再把衣服放进入——揉搓——拧干拿出来——倒掉水——再放水——再揉搓——再拧干拿出来……等等,重于过程的步骤化,少了一步都不行。
而Java面向对象的程序是由对象组成的,每个对象包含对用户的的特定功能部分和隐藏的实现部分。程序中的很多对象来自标准库,还有一些是自定义的。不必关心对象的具体实现,只要能满足用户的需求即可。
例如:用自动洗衣机洗衣服,只需要把衣服丢进洗衣机里,导入洗衣液即可,不关心洗衣机具体怎么洗衣服的。主要是靠对象之间的交互完成的。
面向对象和面向过程并不是一种语言,而是一种解决问题的方法 ,用途尽不相同。
2.类的定义和使用
面向对象程序由对象组成,对象是现实生活中的实体,要使用对象必须先构造对象。而类又是构造对象的模板或蓝图,描述对象的属性,状态,功能,类是一种自定义的类型。
例如:对洗衣机的属性进行描述,属性:品牌,型号,重量,尺寸,颜色等。
功能:快洗,柔洗,烘干等。
定义(创建)类的语法格式:
class为定义类的关键字,后跟类名,{}内是类的主体,对类进行描述和说明。
class 类名{
属性;
功能;
}
例如:class WashMachine{
public String brand; // 品牌
public String type; // 型号
public double weight; // 重量
public double lenght; // 长
public double weidth; // 宽
public double height; // 高
public String color; // 颜色
public void WashClothes(){ // 洗衣服
System.out.println("洗衣功能");
}
public void dryClothes(){ // 脱水
System.out.println("脱水功能");
}
public void SetTime(){ // 定时
System.out.println("定时功能");
}
}
注意事项:
1.程序中可以有若干个类,但只能与一个类被public修饰且public所修饰的类必须与文件名相同
2.若要修改public类名则需要右击(src下面的)文件名——Refactor——Rename——输入类名即可(只适用于一个文件中只有一个类,若含有多个类则不能通过此重命名)
3.类名要采取大驼峰的方式,如洗衣机 WashMachine。
4.main方法所在的类要用public 修饰
5.在类中定义的变量称为成员变量,主要说明其属性。其作用范围在整个类中都有效,其生命周期与对象同步,随着对象的创建而诞生,随着对象被垃圾回收而消失,储存在内存的堆中,若不赋初值则为默认值。在类中定义的方法为成员方法,注意不加static后面详细说明,主要说明其功能。
3.类的实例化
Java中有基本数据类型和引用类型还有boolean char类型,而我们定义的类属于一种新的类型,可以使用这些类来定义实例(对象),用类类型创建对象的过程称为类的实例化,Java中采用new关键字配合类名实例化对象,类可以用来定义引用变量,引用变量通过.访问对象中的属性和方法从而给对象赋值,同一个类可以创建多个实例(占用实际的物理空间)
例如:
WashMachine wash1=new WashMachine(); //通过new实例化对象1
wash1.brand="haier"; //通过.访问成员属性(成员变量)
wash1.type="pyroe";
wash1.weight=55.78;
wash1.WashClothes(); //通过.访问成员方法
WashMachine wash2=new WashMachine(); //通过new实例化对象2
wash2.brand="meidi"; //通过.访问成员属性(成员变量)
wash2.type="fghje";
wash2.weight=57.99;
wash2.WashClothes(); //通过.访问成员方法
可以实例化多个对象
public static void main(String[] args) {
WashMachine wash1=new WashMachine(); //通过new实例化对象1
WashMachine wash2=new WashMachine(); //通过new实例化对象2
WashMachine wash3=new WashMachine(); //通过new实例化对象3
WashMachine wash4=new WashMachine(); //通过new实例化对象4
}
4.成员变量
成员变量分为实例成员变量(储存在对象里)和静态成员变量(属于类储存在JVM的方法区内),我们现在所定义的是实例成员变量,对于成员变量(对象的属性)若未对其赋初值,则其为默认值(null),基本数据类型的默认值为0,boolean类型的默认值为false,char类型的默认值为"\u0000",引用类型的默认值为null,
WashMachine wash1=new WashMachine(); //通过new实例化对象1
System.out.println("未初始化时为:"+wash1.brand); //未初始化时成员变量的值
wash1.brand="haier"; //通过.访问成员属性(成员变量)给其赋值
System.out.println("初始化后为:"+wash1.brand); //赋值后的成员变量的值
运行结果:

5.观察内存中的分布
局部变量、引用变量储存在栈,对象储存在堆上 ,(实例化)成员变量储存在对象里

如图所示:引用变量wash1储存在栈上,存的是对象的地址,指向对象的,每新定义一个引用变量就会在栈上为其分配一块内存;实例化对象的时候会在堆上为对象分配(new)内存,里面储存成员的属性(成员变量);引用(变量)是指向对象的,wash1引用(变量)指向new WashMachine对象;
注意实例化多个对象的时候,每个引用指向的对象都是不一样的
public static void main(String[] args) {
WashMachine wash1=new WashMachine(); //通过new实例化对象1
WashMachine wash2=new WashMachine(); //通过new实例化对象2
WashMachine wash3=new WashMachine(); //通过new实例化对象3
WashMachine wash4=new WashMachine(); //通过new实例化对象4
}

6.引用的灵魂拷问
(1)看下面一段代码,如果引用不想指向对象或者不知道指向哪个对象时,先将设为null(空),但后面我们想用这个引用访问对象里的成员变量是否可以呢?
public static void main(String[] args) {
WashMachine wash1 = null;
wash1.brand = "haier";
}
其结果是:
定义引用的时候并没有指向对象,也就没有为其分配对象的地址,这时你想利用引用访问对象里的成员变量就会造成空指针异常。
(2)引用可以指向引用吗? 例如:看下面的代码是否正确
public static void main(String[] args) {
WashMachine wash1=new WashMachine(); //通过new实例化对象1
WashMachine wash2=new WashMachine(); //通过new实例化对象2
wash1=wash2;
}
答案是:代码是无误的,但这种说话不太准确,你再想想引用是指向谁的,要如同孙悟空念经一样要把这句话在心里默念八百遍:引用是指向对象的;所以你可以说引用指向(另一个引用所指向的)对象,但并不能说引用指向引用; 来看一下内存中的分布来加深一下理解
先看执行前两行代码内存中的分布,分别为wash1、wash2分配空间和指向对象

再看执行到第三行代码时内存中分布发生了怎样的变化:

聪明的你一定可以看出wash1的指向对象发生了变化,不再指向0x999这块内存所存放的对象,也不再存放这块地址,而指向了0x555这块地址所存放的对象,值也变成了这块地址,这块地址是wash2所指向的对象的地址,若是不太好理解的话可以想一下C语言中
int a=10;
int b=20;
a=b;
定义a的值为10;b的值为20,进行a=b;时是将b的值20赋给了a,使得a为20,b的值并不会改变还是20,a和b的值都为20;引用同样如此,进行wash1=wash2;时 将wash2所指向的对象也让wash1指向,wash2的内容并不会改变,两者同时指向同一个对象;
(3)一个引用可以同时指向多个对象吗?例如:看下面代码
public static void main(String[] args) {
WashMachine wash1=new WashMachine(); //通过new实例化对象1
wash1=new WashMachine(); //wash1指向新的对象
wash1=new WashMachine(); //wash1指向新的对象
wash1=new WashMachine(); //wash1指向新的对象
}
虽然实例化对象时每行代码都是一样的,可不要以为wash1从头到尾指向的同一个对象,储存的同一个地址,可千万不能这样认为,那样你可就太单纯了,每一行的 wash1=new WashMachine();都在堆上为新对象分配了新的空间,每个wash1储存的地址都不一样,来看详细内存分布,加深理解

可以看到wash1先后指向了不同的对象,也储存了不同对象的地址。但最终只指向了一个对象,只储存了一个对象的地址,无论你指向几个对象,最终引用只会指向最后指向的对象,储存最后所指向对象的地址;机制的你是不是又联想到了C语言中的多次赋值,无论你给一个变量赋多少个不同的值,它最终只会储存最后所赋的值,详细的C语言代码我就不啰嗦啦,你肯定知道的,我已经叨叨了很多了,就到这里吧,see you !


