精华内容
下载资源
问答
  • 新手小白学JAVA 面向对象对象 封装

    万次阅读 多人点赞 2021-05-06 15:58:57
    面向对象概念 面向对象其实是一种编程思想,通过它可以把生活中复杂的事情变得简单化,从原来的执行者变成了指挥者。 面向对象是基于面向过程而言的。 面向过程强调的是过程,比如: 打开冰箱门 2. 把大象放进去 3. ...

    面向对象概念

    在学习面向对象之前,我们可以先了解一下面向过程。面向过程是一种思想,意思是我们要做任何事,都需要亲力亲为,强调的是过程。
    面向对象也是一种编程思想,相对于面向过程,我们可以由原来问题的执行者变为指挥者,进而把生活中很多复杂的问题变得简单化。

    面向过程强调的是过程,比如,把大象装冰箱,一共分3步:
    第1步:打开冰箱门
    第2步:把大象放进去
    第3步:关上冰箱门
    而面向对象强调的是结果,比如:
    什么样的冰箱?什么样的大象?谁负责把大象装进去?
    有没有发现,如果是面向对象的话,干这件事的主体并不是你自己,你变成了一个指挥者?

    再比如,衣服脏了,我们可以让女盆友帮忙洗,不需要关注中间过程是怎么洗的,就可以拿到干净的衣服,当然,这首先需要有一个对象(加油哦)~

    还有,当我们想吃一道菜,其实并不需考虑这道菜是怎么做的,怎么送达的,只需点菜即可.传菜和做菜都有具体的对象来完成具体的功能.我们不需要关注实现的过程,只需要关注结果就好。
    在这里插入图片描述

    这就是我们所说的面向对象的编程思想(OOP,Object Oriented Programming)

    如果面试官问什么是面向对象?你答万物皆对象!额,不建议这样做哈,因为我们还没到大佬的这个高度,还是最好举例。
    就像是你说 : 空即是色 色即是空…信你个鬼鬼

    2 面向对象的三大特征

    1. 封装: 把相关的数据封装成一个“类”组件
    2. 继承: 是子类自动共享父类属性和方法,这是类之间的一种关系
    3. 多态: 增强软件的灵活性和重用性

    3 类和对象

    3.1 类

    1. Java语言最基本单位就是类,类似于类型。
    2. 类是一类事物的抽象。
    3. 可以理解为模板或者设计图纸。

    3.2 对象

    每个对象具有三个特点:对象的状态,对象的行为和对象的标识。

    1. 对象的状态用来描述对象的基本特征。
    2. 对象的行为用来描述对象的功能。
    3. 对象的标识是指对象在内存中都有一个唯一的地址值用来和其他对象区分开来。
    4. 类是一类事物的抽象,对象是具体的实现。

    3.3 类和对象的关系

    1. 计算机语言来怎么描述现实世界中的事物的? 属性 + 行为
    2. 那怎么通过java语言来描述呢?
      我们可以通过类来描述一类事物,用成员变量描述事物的属性,用方法描述事物的行为.

    3.4 练习:类的创建使用

    在编写代码之前,我们需要分析下需求:
    比如我们要把手机这一类事物抽象成代码:
    那么这个事物的类型就是"手机",可以用类来描述.
    类中包含的就是手机抽取出来的共性的属性与功能.

    手机的属性:颜色,尺寸,品牌,价格
    手机的功能功能:打电话,发短信,听音乐

    对象:除此之外,我们还可以创建对象,就相当于是照着图纸制造出来的一个个的手机,比如1号手机对象,包含特有的成员变量和方法
    我们通过class关键字创建类,通过new关键字创建对象。
    接下来我们开始编码吧!
    创建包: cn.tedu.oop
    创建类: TestCreateClass.java

    package cn.tedu.oop;
    /**本类用来练习面向对象
     * 分析手机事物:--通过类来描述
     * 属性:品牌 价格 尺寸 颜色
     * 功能:打电话 发短信 听直播
     * */
    //在一个java文件中可以写多个class,但是被public修饰的只能有一个,而且这个类的名字就是文件名
    public class TestCreateClass {
    	public static void main(String[] args) {
    		//2.在main()中通过new关键字来创建对应类的对象
    		Phone p = new Phone();
    		//3.通过.来完成对象功能的调用
    		p.call();
    		p.message();
    		p.learn();
    		//4.通过.来查看对象的属性值
    		System.out.println(p.brand);
    		System.out.println(p.price);
    		System.out.println(p.size);
    		System.out.println(p.color);
    		
    	}
    }
    //1.通过class关键字创建手机类--用来描述手机这一类事物--特征+行为
    //类是一类事物的抽象,只抽象的规定这一类事物的特征和行为
    class Phone{
    	//特征(属性)--类的成员变量来描述--位置:类里方法外
    	String brand;//品牌
    	double price;//价格
    	double size;//尺寸
    	String color;//颜色
    	
    	//行为(功能)--类的方法来描述--修饰符 返回值类型 方法名(参数列表){方法体}
    	public void call() {
    		System.out.println("正在打电话");
    	}
    	public void message() {
    		System.out.println("正在发短信");
    	}
    	public void learn() {
    		System.out.println("正在看直播");
    	}
    }
    

    3.5 对象在内存中的存储

    Java把内存分成5大区域,我们重点关注栈和堆。

    1. 一般来讲局部变量存在栈中,方法执行完毕内存就被释放
    2. 对象(new出来的东西)存在堆中,对象不再被使用时,内存才会被释放
    3. 每个堆内存的元素都有地址值
    4. 对象中的属性都是有默认值的
      TIPS: 栈与队列指的是一种数据的结构。
      栈:先进后出(FILO – First In Last Out)
      队列:先进先出(FIFO – First In First Out)
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    3.6 练习2:创建多个对象

    package cn.tedu.oop;
    /**本类用来练习面向对象
     * 分析手机事物:--通过类来描述
     * 属性:品牌 价格 尺寸 颜色
     * 功能:打电话 发短信 听直播
     * */
    //在一个java文件中可以写多个class,但是被public修饰的只能有一个,而且这个类的名字就是文件名
    public class TestCreateClass {
    	public static void main(String[] args) {
    		//2.在main()中通过new关键字来创建对应类的对象
    		Phone p = new Phone();
    		//3.通过.来完成对象功能的调用
    		p.call();
    		p.message();
    		p.learn();
    		//4.通过.来查看对象的属性值
    		System.out.println(p.brand);
    		System.out.println(p.price);
    		System.out.println(p.size);
    		System.out.println(p.color);
    		
    		//5.创建第二个对象
    		Phone p2 = new Phone();
    		
    		//5.1调用模板里的功能
    		p2.call();
    		p2.message();
    		p2.learn();
    		
    		//5.2给对象的属性设置值
    		p2.brand = "HUAWEI";
    		p2.price = 8888.88;
    		p2.size = 5.6;
    		p2.color = "中国红";
    		
    		//5.3通过.来查看对象的属性值
    		System.out.println(p2.brand);
    		System.out.println(p2.price);
    		System.out.println(p2.size);
    		System.out.println(p2.color);
    		
    	}
    }
    //1.通过class关键字创建手机类--用来描述手机这一类事物--特征+行为
    //类是一类事物的抽象,只抽象的规定这一类事物的特征和行为
    class Phone{
    	//特征(属性)--类的成员变量来描述--位置:类里方法外
    	String brand;//品牌
    	double price;//价格
    	double size;//尺寸
    	String color;//颜色
    	
    	//行为(功能)--类的方法来描述--修饰符 返回值类型 方法名(参数列表){方法体}
    	public void call() {
    		System.out.println("正在打电话");
    	}
    	public void message() {
    		System.out.println("正在发短信");
    	}
    	public void learn() {
    		System.out.println("正在看直播");
    	}
    }
    

    在这里插入图片描述
    p2.brand = “HUAWEI”;
    就是先到栈内存中找到p2中保存的唯一的地址值
    然后根据地址值找到对应的Phone对象,并对其对应的属性值进行修改
    p2.eat();
    也是先到栈内存中找到p2中保存的唯一的地址值
    然后根据地址值找到对应Phone对象,执行Phone对象的eat()方法

    4 封装

    4.1 概述

    封装是隐藏对象的属性和实现细节,仅仅对外提供公共的访问方式,比如类和方法
    好处:

    1. 提高安全性
    2. 提高重用性

    4.2 private关键字

    是一个权限修饰符 ,可以用来修饰成员变量和成员方法.被私有化的成员只能在本类中访问

    4.3.1练习:封装的必要性

    创建包: cn.tedu.oop
    创建类: TestPrivate1.java

    package cn.tedu.oop;
    /*本类用于测试封装的必要性*/
    public class TestPrivate1 {
        public static void main(String[] args) {
            //5.创建对象进行测试
            User u = new User();
            u.name = "西门庆";
            System.out.println(u.name);
            //需要封装属性,如果不封装的话,就可以直接修改属性的值
            //不需要按照我们预先设置好的方式也能操作
            //u.money = 1000000;
            //System.out.println(u.money);
            u.setMoney(109999);
            System.out.println(u.queryMoney());
    
        }
    }
    //1.创建一个用户类User
    class User{
        //2.定义用户类的属性
        public String name;
        private double money = 10000;
    
        //3.提供方法1:可以用来查询当前账户的余额
        public double queryMoney(){
            /*后续可以添加权限的校验*/
            return money;
        }
        //4.提供方法2:可以设置当前账户的余额
        public void setMoney(double money){
            /*后续可以添加权限的校验*/
            this.money = money;
        }
    }
    

    4.3.2 练习:封装学生案例

    创建包: cn.tedu.oop
    创建类: TestPrivate2.java

    package cn.tedu.oop;
    /*本类用于测试面向对象第一大特性--封装*/
    public class TestPrivate2 {
        public static void main(String[] args) {
            //4.创建学生类对象s
            Student s = new Student();
            //5.通过对象操作学生类的属性与方法
            System.out.println(s.name);//null
            s.study();//正在学习中。。。
            /*2.subject属性在Student类中被private修饰,所以此处无法直接修改或获取值*/
            //s.subject = "Java培优";
            //System.out.println(s.subject);//Java培优
            //6.3在main()里操作subject属性
            s.setSubject("CGB");//设置值
            System.out.println(s.getSubject());//获取值
            //7.3操作属性sno
            s.setSno(1);
            int snumber = s.getSno();
            System.out.println("接到的学号是:"+snumber);
            System.out.println(s.getSno()+"直接打印的");
        }
    
    }
    
    //1.描述学生这一类型
    class Student{
        //2.特征:学号 姓名 科目--成员变量/属性
        //7.1封装属性,用private修饰这个属性
        private int sno;//学号
        String name;//姓名
        /*1.private是一个修饰符,被它修饰的资源只能在本类中使用,是权限最小的修饰符*/
        //6.1封装subject属性
        private String subject;//科目
    
        //7.2添加sno属性对应的get()与set()
        public int getSno() {
            return sno;
        }
        public void setSno(int sno) {
            this.sno = sno;
        }
    
        //6.2我们需要提供一个公共的方式,供外界操作subject的属性值
        //右键空白处->Generate->Getter and Setter->选中subject属性->OK
        public String getSubject() {
            /*4.如果一个方法需要返回结果,那么这个方法定义的返回值类型就不再是void了
            * 至于具体设置成什么类型,与返回值的类型保持一致
            * 比如我们要返回的subject是String类型,所以方法的返回值类型为String
            * 返回值通过关键字return进行返回*/
            return subject;
        }
        public void setSubject(String subject) {
            /*3.如果一个类中的成员变量与局部变量同名
            * 需要使用this关键字指定,我们规定this指定的那个是成员变量*/
            this.subject = subject;
        }
    
        //3.功能:学习 吃饭 睡觉--方法
        public void study(){
            System.out.println("正在学习中。。。");
        }
        public void eat(){
            System.out.println("正在吃饭ing...");
        }
        public void sleep(){
            System.out.println("我一点也不想睡觉,就想学Java!");
        }
    }
    

    TIPS:如何封装?封装后的资源如何访问?
    我们可以使用private关键字来封装成员变量与方法
    如何访问私有资源?
    关于成员变量:
    setXxx – 对外提供公共的设置值方式
    getXxx – 对外提供公共的获取值方式
    关于成员方法:
    把私有方法放在公共方法里供外界调用即可

    5 拓展:OOP综合练习

    创建包:cn.tedu.oop
    创建类:TestCar

    package cn.tedu.oop;
    /*本类用于面向对象的巩固练习*/
    public class TestCar {
        //创建程序的入口函数main()
        public static void main(String[] args) {
            //3.创建汽车类对象c
            Car c = new Car();
            //4.通过汽车类对象c设置属性值
    //        c.color = "暗夜紫";
    //        c.brand = "BMW";
    //        c.price = 200;
    //        c.length = 0.2;
            //5.查看刚刚设置好的属性值
    //        System.out.println(c.brand);
    //        System.out.println(c.price);
    //        System.out.println(c.color);
    //        System.out.println(c.length);
            //6.通过c对象调用汽车类的方法
            c.start();
            //c.stop();
            //7.3调用提供的set与get方法,设置并获取对应属性的值
            c.setBrand("特斯拉");
            c.setColor("black");
            c.setPrice(200.02);
            c.setLength(3);
            System.out.println(c.getBrand());
            System.out.println(c.getColor());
            System.out.println(c.getLength());
            System.out.println(c.getPrice());
            //8.3 调用公共方法来实现私有方法功能的使用
            c.start();
        }
    }
    //1.抽象汽车这一类事物的属性与行为,封装成一个类组件
    class Car{
        //2.属性--用成员变量来描述
        //7.1封装所有的属性值--使用private修饰
        private String color;
        private String brand;
        private double price;
        private double length;
        //7.2 生成所有属性的get与set方法
        /*右键空白处->Generate->Getter and Setter->按住Shift全选所有属性生成即可*/
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(double price) {
            this.price = price;
        }
    
        public double getLength() {
            return length;
        }
    
        public void setLength(double length) {
            this.length = length;
        }
    
        //3.行为--用方法来描述
        //8.2 可以在本类公共的方法里,调用私有方法
        public void start(){
            System.out.println("汽车开动了~");
            stop();//我们通过方法名+参数列表确定要调用哪个方法
        }
        //8.1封装方法,通过private修饰符
        private void stop(){
            System.out.println("汽车停止了~");
        }
    }
    

    6 访问控制符

    用来控制一个类,或者类中的成员的访问范围。
    在这里插入图片描述
    TIPS:default是表示不写修饰符,默认,如果写default单词来修饰会报错

    拓展7 匿名对象

    没有名字的对象,是对象的简化表示形式。
    使用场景:
    当被调用的对象只调用一次时(多次会创建多个对象浪费内存)
    Demo d = new Demo();
    d.sleep();
    d.game();
    //这个d就是对象的名字。
    也可以写成:
    new Demo().show();//创建了一个对象调方法
    new Demo().game();//又创建了一个对象调方法

    展开全文
  • 一个对象在内存中究竟是怎样进行布局的,如何依据代码去确定对象占据的大小,本文将进行粗略地探讨。 对象在内存中的布局,主要3个组成部分,包括对象头,实例数据与对齐填充。确定对象的大小,也是从这3个组成...

    一个对象在内存中究竟是怎样进行布局的,如何依据代码去确定对象占据的大小,本文将进行粗略地探讨。

    对象在内存中的布局,主要有3个组成部分,包括对象头,实例数据与对齐填充。确定对象的大小,也是从这3个组成部分的入手。


    对象头

    其中对象头中又包括Mark Word与Klass Word。当该对象是一个数组时,对象头还会增加一块区域,用来保存数组的长度。以64位系统为例,对象头存储内容如下图所示:

    |---------------------------------------------------------------------------------------------------------------|
    |                                              Object Header (128 bits)                                         |
    |---------------------------------------------------------------------------------------------------------------|
    |                        Mark Word (64 bits)                                     |      Klass Word (64 bits)    |       
    |---------------------------------------------------------------------------------------------------------------|
    |  unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:0 | lock:01 |     OOP to metadata object   |  无锁
    |----------------------------------------------------------------------|---------|------------------------------|
    |  thread:54 |         epoch:2      | unused:1 | age:4 | biased_lock:1 | lock:01 |     OOP to metadata object   |  偏向锁
    |----------------------------------------------------------------------|---------|------------------------------|
    |                     ptr_to_lock_record:62                            | lock:00 |     OOP to metadata object   |  轻量锁
    |----------------------------------------------------------------------|---------|------------------------------|
    |                     ptr_to_heavyweight_monitor:62                    | lock:10 |     OOP to metadata object   |  重量锁
    |----------------------------------------------------------------------|---------|------------------------------|
    |                                                                      | lock:11 |     OOP to metadata object   |    GC
    |---------------------------------------------------------------------------------------------------------------|

    Mark Word

    该区域主要存储hashcode、gc年龄、锁标志等。在32位系统上,Mark Word为32位,在64位系统上,为64位,即8个字节。Mark Word在不同的锁标志(lock)下,结构也不尽相同。当然,lock相同时,比如lock=01,这时候需要借助偏向锁标记(biased_lock)来具体确定对象是否存在偏向锁。

    关于结合Mark Word讲锁的升级,可能要另外篇幅。不过,可以先看我的另外一篇文章Synchronized的优化,大致了解一下锁的优化。

    Klass Word

    该区域存储对象的类型指针,该指正指向对象类元数据(类元数据都在方法区中,对方法区不熟悉的同学,可以先参考我的另外一篇文章灵性一问——为什么用元空间替换永久代?),虚拟机能够通过这个指针,来确定该对象到底是哪个类的实例。在32位系统上,该区域占用32位,在64位系统上,占用64位,但是!当64位机器设置最大堆内存为32G以下时,将会默认开启指针压缩,将8字节的指针压缩为4字节。当然也可以使用+UseCompressedOops直接开启指针压缩。

    Array Length

    前面说过,如果对象是一个数组,那么对象头会增加一个额外的区域,用来记录数组的长度。在32位系统上,该区域占用32位,在64位系统上,占用64位,同样的,如果开启指针压缩,则会压缩到32位。

    可以看得出来,一个非数组的对象的对象头占用12个字节,即Mark Word(8)+Klass Word(4)。


    实例数据

    基本数据类型占用的长度如下:

    类型

    占用字节长度

    byte

    1

    short

    2

    int

    4

    long

    8

    float

    4

    double

    8

    char

    2

    boolean

    1

    对于引用变量占用的长度,同样视系统位数而定。32位系统占用4字节,64位系统8字节,开启指针压缩那就占用4字节。

    实例数据部分只会存放对象的实例数据,并不会存放静态数据。此外,子对象的实例数据部分会继承父类所有实例数据,包括私有类型,这里可以理解为子类拥有父类所有类型的成员变量,但在子类中无法直接访问这些私有实例变量。


    对齐填充

    这里的对齐填充有两方面:

    (1)HotSpot虚拟机规定对象的起始地址必须是8的整数倍,也就是要求对象的大小必须是8的整数倍。因此如果一个对象的对象头+实例数据占用的总内存没有达到8的倍数时,会进行对齐填充,将总大小填充到最近的8的倍数上。

    (2)字段与字段之前也需要对齐,字段对齐的最小单位是4个字节。

    可以这样理解,虚拟机每次会为字段发放一个最近的4倍数的一个盒子。比如,有个类的字段有一个boolean和一个int,这时候先为boolean发放第一个大小为4字节的盒子,将boolean放入其中,占用1个字节,浪费3个字节,因为int占用4个字节,根本放不下,需要虚拟机再分配一个大小为4的盒子。

    虚拟机不会按照字段声明的顺序去给字段分配盒子,而是会进行重排序,使得物尽其用。比如一个类有以下变量:char、int、boolean、byte。如果按照声明顺序去分配盒子的话,则需要为char分配一个盒子,浪费2个字节。再为int分配一个盒子,这个盒子正好满了,没有浪费。接着为boolean分配一个盒子,浪费3个字节。最后为byte分配一个盒子,又浪费3个字节。

    在进行重排序后,此时可以按照int(4)、char(2)+boolean(1)+byte(1)的顺序,虚拟机可以只分配2个盒子,大大减少内存浪费。但是引用类型的字段必定在最后才分配。


    例子

    例子位于64位机器上,其都开启指针压缩。

    (1)实例化一个没有任何属性的空对象,那么这个空对象占用的内存大小为多少呢?

    很简单,对象头占用12字节,还会利用4字节进行填充,一共占用16字节。

    (2)实例一个具有四个不同属性的对象

    class Test {
        public char charP;
        public int intP;
        public boolean booleanP;
        public byte byteP;
    }

    这就是对齐填充部分举的例子,对象头占用12字节,实例数据占用8字节,此时一共20字节,则对象填充需要占用4字节,一共占用24字节。

    我们使用一个jol(Java Object Layout)工具来分析Test对象占据的内存大小。只要在maven项目中引入这个依赖就好:

            <dependency>
                <groupId>org.openjdk.jol</groupId>
                <artifactId>jol-core</artifactId>
                <version>0.8</version>
            </dependency>

    然后在代码中这样调用:

    package com.yang;
    
    import org.openjdk.jol.info.ClassLayout;
    
    public class Main {
        public static void main(String[] args) {
            Test test = new Test();
            System.out.println(ClassLayout.parseInstance(test).toPrintable());
        }
    }
    

    输出如下:

    看的出来,总大小确实为24字节。

    (3)实例化一个具有父类的子类

    class Father {
        public boolean publicFlag;
        private boolean privateFlag;
        public static boolean staticFlag;
    }
    
    public class Test extends Father {
        public boolean publicFlag;
        private int b;
        protected double c;
        Long d;
    }

    猜猜看,实例化一个Test对象后,这个对象占据的内存大小是多少呢?

    这里可能会有几个问题:

    【1】子类的实例数据部分会排除掉父类的私有实例属性privateFlag吗?

    【2】子类的实例数据部分会覆盖掉父类的同名实例属性吗?

    带着这些疑问,我们直接使用jol查看对象内存大小:

    可以看到,子类对象中包含了父类所有的实例变量,且首先分配父类实例变量,再分配子类实例变量。对象头还是占用12字节,父类实例变量占用4字节(包括2个字节的字段填充),子类实例变量占用20字节,对象填充占用4字节,一共占用40字节。

    展开全文
  • 对象对象的引用

    千次阅读 多人点赞 2018-06-02 01:41:28
    最近初学java对于对象对象的引用以及实例化诸多迷惑,查了很多博客和API,现整理自己的理解如下:Java是一种面向对象的语言,采用类和对象的概念。Java中每个对象一种类型,即对象所属的类。类两个主要...

    最近初学java对于对象和对象的引用以及实例化有诸多迷惑,查了很多博客和API,现整理自己的理解如下:

    Java是一种面向对象的语言,采用类和对象的概念。Java中每个对象都有一种类型,即对象所属的类。类有两个主要成员:域(field)和方法(method)。

    1. 域是与一个类或该类的对象相关联的数据的变量。域中存储初值或执行类的方法得到的计算结果。
    2. 方法包含该类的可执行代码。方法由语句构成。方法被调用的方式,以及这些方法所包含的语句最终指导程序的执行。

    对象以及对象的引用

    关键字new用来创建对象。从一个类中创建用一个对象被称为实例化,所以,对象也常被称为实例。

    Java中新创建的对象被放在被称为“堆”的系统存储区中。Java中的对象都通过“对象引用”(object reference)来访问。一个类的变量持有一个对象,实际上是对该对象的引用。当变量不再引用任何对象时,该对象引用就为null。而我们说的把对象传给一个方法实际上是把对象的引用传给一个方法(参考C++中指针的概念)。但是多数情况下,对象和对象引用的区别都被大家忽略。而这又恰恰是理解对象的关键。

    现在这里有一个类:

    class Point{
        public static void main(String[] args){
        System.out.println("hello");
    }

    对于Point类我们创建对象的通常语句为:

    Point point=new Point();

    通常大家以为point即为所创建的类,其实并不是这样,实际上point是我们创建的对象的引用。这个语句可以分解为两部分来看:

    Point point;//①
    point=new Point();//②

    Point是这里自定义的一个类型,即类类型。

    在语句①中经由Point声明了一个类类型的变量point,是Point类引用变量,它存放在栈空间中。也就是用来指向Point的对象的对象引用。但是此时point不是任何对象的引用,其指向为null,因为对象要在语句②中才创建。

    在语句②中由关键字new创建了一个Point的对象,并将之存放在堆中,然后利用操作符“="使得point引用变量指向刚刚创建的在堆中的对象。

    对象本身看不见摸不着,它是堆中的一块内存实体,甚至说对象本身没有名字。Point不是对象,因为一个类可以创建n个对象不可能每一个都叫做Point,point也不是对象它是Point定义的一个变量,经由语句②它成为了对象的引用。有了对象的引用,就可以方便的调用方法等操作。

    对象和对象引用的关系

    ”但是此时point不是任何对象的引用,其指向为null“上一部分我们讲到对象的引用可以指向null。它真正的含义是:

    一个对象的引用可以:指向一个具体的已经创建的对象或者指向null。即对象的引用只有唯一的指向,不能同时指向多个对象,这一点也很好理解,借用指针的概念,一个指针某一时刻只能指向唯一的内存块代表唯一的内存地址。既然point这个引用变量可以被”赋值“操作,那么自然的如果Point类此时通过”point2=new Point();"又创建了一个新的对象2,我们可以有:

    point=point2;

    这样point就成了对象2的引用,对象1和对象2为堆中的不同的内存块。但是point2此时仍旧是对象2的引用,即对象2有两个引用变量指向它。如果把气球比作对象的话,系气球的绳子比作对象的引用,那么对象2这个气球上面系了两个绳子。显然最初创建的对象1上面没有任何绳子系在上面,也就是说它没有“对象引用”,对于这样的对象就要面临被废区收集器(garbage collection)自动回收,从而在堆中消除。但是并不是立即消除,系统会判断在一个合适的时候回收。

    总结起来:对象的引用某一时刻只可以有唯一指向(或null),对象本身可以同时被多个引用变量引用(或0个)。

    得不到



    展开全文
  • 怎样理解对象

    千次阅读 2018-08-01 11:28:59
    1、对象的英文单词是“Object”,它三个方面的意思: (1)目标,目的,宗旨 (2)物,物体,物件 (3)对象,客体,客观  仔细琢磨下这三个意思。首先它“目标”的意思,也就是说这是个实际的东西,我们可以...

    一、万事万物皆对象--理解对象模型
    对象实际上是看待事物的一种方式。它只是我们从现实世界中抽象出来的一种模型,但是这个模型还是有它的定义和概念的。

     

    1、对象的英文单词是“Object”,它有三个方面的意思:
    (1)目标,目的,宗旨
    (2)物,物体,物件
    (3)对象,客体,客观


        仔细琢磨下这三个意思。首先它有“目标”的意思,也就是说这是个实际的东西,我们可以对它做些操作,它是一些动作的受体。其次就是第二层意思,它是物体、物件,现实世界中的任何实际事物或称为“实体”的东西都可以叫作“Object”.第三层含义是哲学上的一个概念,比前两层含义都要抽象,这也是我们所取的“Object”的意思,它就是指一种客观事物的存在,如桌子、人、狗、鱼,蓝天,白云……

     


        对象是件“东西”,什么“东西”都可以称之为对象;你可以对一个对象施加作用(属性->特性),对象会发生一些事件(变化->方法)

     

    2、现实世界中一些具体的对象

        举个栗子,比如一台笔记本电脑,我们将它视为一个对象无非是为了能够更加抽象地描述它,这在编程的过程中很重要,来看看它有哪些需要抽象出来的特性吧~
        在生活中大家应该很熟悉,当你在买一台新的笔记本电脑时,主要考虑的是什么?———笔记本电脑的屏幕大小、屏幕形状、机身总重量、硬盘空间、CPU频率、操作系统……这些都是“笔记本电脑”这个对象所固有的一些性能或制造的参数,这些可以标识出这台笔记本电脑是否受到顾客的欢迎。
        但是,对于现实世界中的一台洗衣机,要考虑的特性就完全不是上面的那些参数和特性了,更多的是会去关注它的容积、耗电量、噪音大小等。还有,对于一架航天飞机,它要考虑的特性会更多,对于一支钢笔,一把伞,针对它们要考虑的就会相对要少一些……从这些例子来看,世间万物的复杂程度不同,我们对它们的关心方面就不同,相应地从它们这些具体事物中抽象出的对象也会各有差别。

     

    3、由现实世界中的事物抽象为对象


        来看看下面这张图,图中列出了3种类型的电脑,以及我们对3个“对象”所关注的特性。相对而言,对于台式机更注重性能,不会关心它的重量,因为它不是为了方便移动而设计的。而对于平板电脑呢,相比较台式电脑而言,没有那么关心它的性能,而是看它是否方便携带及电池的续航能力。而笔记本电脑,考虑因素就处于这两者之间。
        这个例子,向大家说明了如何将现实世界中的各种事物抽象为一个个对象。做法很简单,只要它是一个独立的事物,找出所关注的那几个方面的特性,把这些特性提取出来,就得到了一个抽象之后的“对象”。

     

     

    4、对象之间的差别--事物的属性
        (1)何为对象的属性?
      只知道什么是对象还不行,世界上有无穷多种事物,它们各有特点,互不相同。必须有个办法将我们抽象出的对象互相区分出来才行,这样才能够真实地对现实世界中的事物进行合理的建模与抽象。这个用于区分各个对象特征的部分就称为属性,不同的对象具有不同的属性,借属性这个概念来使各个对象能够得以区分。


        (2)不同对象的属性值不同
        举个例子,如果发现两个笔记本电脑对象的屏幕尺寸大小不同,则它们必然不是同一个对象。
        


        (3)不同对象具有不同的属性
        举个例子,笔记本电脑和平板电脑,其中屏幕大小是两者都有的一个共同属性。它们也具有不同的属性,笔记本电脑的键盘属性,平板电脑的触摸板的属性,等等。

     

        (4)属性与对象间的关系
        举个例子,三角形与正方形都有一个共同的属性--边长。圆形是不具有边长的,只有名称为“直径”的属性。三角形与正方形虽然都具有“边长”,但边长的值并不相同,另外,我们也知道三角形与正方形,边长对它们的一些其他的特性,如周长、面积等的含义是不同的。这些均代表了不同的对象之间属性的关系,可能具有不同的属性或者不同的属性值。

     


      

     

    5、对象与属性的关系
        对于任何一个属性都具有三个方面:属性所属的对象、属性名称、属性的值。只有这三个方面都是相同的,才能判定这两个属性实际上属于同一个。比如,两台笔记本电脑的屏幕大小都是14寸,这才说明“屏幕大小”这个属性是属于同一个。

     


    二、万物皆有变化——对象的方法
    对象是由现实中的事物抽象而来的。我们知道世界上亘古不变的事物几乎是没有的。世间万物都处在不断变化中,当所要关注的对象发生变化时,就必须要有一种相应的办法来描述并反映对象的这个变化的过程和想象。

     

    1、对象的方法定义
        属性只是固定的、没有变化的对象特征而已。但现实世界中的事物都处在不断发展变化中,必须有某种方式来描述这种变化。所以就有了“方法”,它所描述的是对象可以发起的动作,或者是对象可以做的事情等。
       (1)什么是方法?
        举个例子,将一只猫抽象为一个对象——Cat。对于这个对象,我们现在只关注它所拥有的其中一个属性——体重(Weight)。猫能吃老鼠,这样Cat对象就会有一个方法——EatMouse().用这个方法表示猫吃老鼠这个变化过程,在这个过程的前后猫的体重会有所变化。反映到我们抽象后的对象中,就是这个事实,Cat在执行EatMouse()这个方法之后,属性Weight的值发生了变化,这就是对象的变化——方法。
        事实上,方法的定义是这样说的:它是相应的对象可以做的、但不一定会真正去做的事情。从这个定义上来看,上面的EatMouse()方法是为Cat对象所有的,如果在定义一个对象——狗(Dog),那么它就不可以拥有EatMouse()方法。

     

    2、方法与对象间的关系

        不同的对象所拥有的方法可能不一样,但方法并不是一个对象所专属的事情。

        如下图:

     

     

     

     

     

     

     

    展开全文
  • 对象赋值 如同基本类型的赋值语句一样,同一个类的对象之间也是可以进行赋值操作的,即将一个对象的值赋给另...给对象赋值和调用拷贝构造函数初始化另一个对象行为是类似的,但是有所区别,下面讲到(实际上调用的...
  • 面向对象

    万次阅读 多人点赞 2018-05-19 16:59:57
    Java语言的面向对象技术包括了面向对象和面向过程的基本概念,面向对象的特征,Java语言的类,对象,修饰符,抽象类等一系列的知识点首先让我们来了解一下什么是对象? 没错!面向对象我们肯定需要先知道对象到底是...
  • Browser Object Model:浏览器对象模型,用来访问和操纵浏览器窗口,使js能力与浏览器“对话”,通过使用BOM,可移动窗口、更改状态文本、执行其他不与页面内容发生直接联系第操作,且没有相关标准,但被广泛支持。...
  • 面向对象总结

    千次阅读 多人点赞 2019-09-03 23:17:49
    面向对象是宏观的上为用户解决功能需求,用户只需要知道怎么对象实现功能就好了,具体底层如何实现不用操心,不过面向对象的最底层还是以面向过程的方式实现,但面向对象对比面向过程,减少了学习成本。...
  • C++ 栈对象对象 理解

    千次阅读 多人点赞 2014-08-20 16:20:00
    这两种方式是区别的。 1、静态建立类对象:是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造...
  • Python中面向对象(学习笔记)

    万次阅读 多人点赞 2020-06-15 09:29:18
    文章目录一、面向过程与面向对象简述面向过程编程面向对象编程二、类和对象对象(实例)类和对象的关系三、类的定义四、类中的成员类属性实例函数(对象函数,成员函数)实例函数和普通函数的区别关于self创建对象...
  • 如果new 一个对象,用free去释放,会有什么问题? 587人阅读 收藏 版权声明:本文为博主原创文章,未经博主允许不得转载。 关于C++里面的NEW/DELETE和maclloc/free。 昨天面试的时候被问到这个问题,...
  • 对象的每个属性或方法都一个名字,而每个名字都映射到一个值。正因为这样,我们可以把ECMAScript的对象想象成散列表:无非就是一组名对值,其中值可以是数据或函数。  创建自定义对象最简单的方式就是创建一个...
  • new一个对象,到底发生什么

    千次阅读 2017-12-22 15:14:36
     Java是一门面向对象的编程语言,在Java程序运行过程中无时无刻都有对象被创建出来,在语言层面只是使用new关键字,而在虚拟机中,对象的创建又是怎样一个过程呢?  1.类加载检查  虚拟机遇到一条new 指令...
  • 在运行时进行节点的创建(cc.instantiate)和销毁(node.destroy)操作是非常耗费性能的,因此我们在比较复杂的场景中,通常只有在场景初始化逻辑(onLoad)中才会进行节点的创建,在切换场景时才会进行节点的销毁。...
  • JS原生对象与内置对象

    千次阅读 2018-03-05 04:27:38
    一、JS的对象和类型 JS中的所有事物都是对象,包括但不限于字符串、数值、数组、函数等等,还包括自定义对象。 在红宝书中,将JS分为五种基本类型:null、undefined、number、string、boolean和一种复杂类型:...
  • C++对象计数

    千次阅读 2019-01-26 12:25:33
    例如,你一个Widget类,你想知道一共在运行时一共创建了多少个Widget对象。一个简单可行的方法是在Widget内部创建一个static counter,当对象创建时增加计数器的值,当对象销毁时减少计数器的值。同时,也要创建一...
  • 多层嵌套对象获取底层对象属性

    千次阅读 2018-01-07 20:00:09
    Map,List,Set,Page,自定义包装类等等,且包装层还嵌套层,如Map,Page,仅仅是通过反射获取这些包装之下实际Model就很花费精力,就想能不能将这些逻辑抽象出来,写个特定的工具类,能很方便的剥离这些外层,...
  • GC分代年龄:记录幸存者区对象被GC之后的年龄age,,一般age为15之后下一次GC就直接进入老年代 锁状态标志:记录一些加锁的信息 ② 类型指针:是对方法区中类元信息的引用 ③ 实例数据:真实记录一个对象包含的...
  • 关于C++里面的NEW/DELETE和maclloc/free。 如果new 一个对象,用free去释放,会有什么问题?
  • JSP内置对象和EL内置对象

    千次阅读 2014-01-04 21:42:20
    首先说一下JSP内置对象:   JSP内置对象类型映射表  对象名 类型 作用域  request javax.servlet.ServletRequest RequestScope  response javax.serv
  • 面向对象思想————不看后悔!... 前言: 整理这份资料的目的是为了帮助朋友们能够...但其中不免许多漏洞及错误,也还请前辈提出宝贵的更改意见,毕竟交流让我们不断的进步。 技术是日新月异的,他不会等待你的成长。
  • 判断对象为垃圾对象的方法为:引用计数法和可达性分析法。 Object object = new Object(); // 不是垃圾对象 object = null; // 此时为垃圾对象 System.gc(); // 提示给gc进行回收垃圾,只是提示而已,不代表立即...
  • 面向对象分析与设计——对象模型

    千次阅读 2014-10-22 09:18:58
    对象模型  对象模型包括:抽象、封装、模块化、层次结构、类型、并发和持久   2.1 对象模型的演进   OO建立在以前技术的最佳思想之上。两大趋势:小规模→大规模;高级程序设计语言;   2.1.1 程序...
  • 详解Python中的可哈希对象与不可哈希对象(二)

    千次阅读 多人点赞 2019-10-30 16:49:52
    前言:我们经常听见很多的概念,哈希值,哈希表,可哈希对象,不可哈希对象,散列表,字典,映射,等等,那么这么多的概念后面到底又什么区别和联系,它们的本质又是怎么样的,本此系列文章将针对这些概念进行...
  • 讨论这个问题需要限定在具体的虚拟机和集中在某一个内存区域上才有意义。我们这个所说的是Sun的HotSpot虚拟机的Java堆内存区域,深入探讨HotSpot虚拟机在Java堆中对象的分配、布局和访问全过程。本文大纲: 一、 ...
  • Java对象的销毁

    千次阅读 2019-05-10 20:05:32
    对象使用完之后需要对其进行清除。对象的清除是指释放对象占用的内存。在创建对象时,用户必须使用 new 操作符为对象分配内存。不过,在清除对象时,由系统自动进行内存回收,不需要用户额外处理。这也是 Java 语言...
  • 面向对象——类

    千次阅读 2020-04-07 19:13:16
    类:存储数据一种结构体,是...备注:类是创建对象的模板,只有了类之后,可以创建对象。 创建对象的格式: 类名 对象名字 = 关键字(new)类名([参数]); 创建对象的过程:通过调用类的实例(对象)构造函数...
  • Java回收对象的标记 和 对象的二次标记过程   一、对象的标记 ...引用计数实现起来比较简单,就是给对象添加一个引用计数器,每当一个地方引用它时就加1,引用失效时就减1,当计数器为0的时候就标记为可
  • 对象 为什么要有对象 function printPerson(name, age, sex....) { } // 函数的参数如果特别多的话,可以使用对象...现实生活中:万物皆对象对象是一个具体的事物,一个具体的事物就会有行为和特征。 举例: 一部...
  • 在vue的当我们用watch属性监听一个对象时;例如; var app=new({ ...},/只有当obj中name的属性值改变时才会触发这个函数/ obj:{ handler(){ }, deep:true,/只要当obj中的值改变就会触发这个函数/ }...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 331,203
精华内容 132,481
关键字:

怎样才会有对象