【JAVA类与对象----1】

发布于:2022-11-11 ⋅ 阅读:(839) ⋅ 点赞:(0)

目录

1.什么是面向对象(oop)

2.类的定义和使用

3.类的实例化

4.成员变量

5.观察内存中的分布

6.引用的灵魂拷问


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 !


网站公告

今日签到

点亮在社区的每一天
去签到