• java 对象(翻译自Java Tutorials)


    原文出自 http://www.cnblogs.com/ggjucheng/archive/2012/11/28/2793158.html

    对象

    一个典型的java程序会创建很多对象,就像你所知道的,这些对象通过方法调用进行交互。通过对象交互,程序可以完成很多任务,例如实现图形界面运行动画,通过网络发送或者接收信息。一个创建好的对象,当它完成任务时,它的资源也会被其他对象重复使用。

    这里有一个小程序,叫CreateObjectDemo,它创建三个对象:一个Point对象和两个Rectangle对象。编译这个程序,我们需要三个源码文件。

    public class CreateObjectDemo {
    
        public static void main(String[] args) {
            
            // Declare and create a point object
            // and two rectangle objects.
            Point originOne = new Point(23, 94);
            Rectangle rectOne = new 
                Rectangle(originOne, 100, 200);
            Rectangle rectTwo =
                new Rectangle(50, 100);
            
            // display rectOne's width,
            // height, and area
            System.out.println("Width of rectOne: "
                               + rectOne.width);
            System.out.println("Height of rectOne: "
                               + rectOne.height);
            System.out.println("Area of rectOne: "
                               + rectOne.getArea());
            
            // set rectTwo's position
            rectTwo.origin = originOne;
            
            // display rectTwo's position
            System.out.println("X Position of rectTwo: "
                               + rectTwo.origin.x);
            System.out.println("Y Position of rectTwo: "
                               + rectTwo.origin.y);
            
            // move rectTwo and display 
            // its new position
            rectTwo.move(40, 72);
            System.out.println("X Position of rectTwo: "
                               + rectTwo.origin.x);
            System.out.println("Y Position of rectTwo: "
                               + rectTwo.origin.y);
        }
    }

    这个程序创建对象,操控对象,并显示多个对象的信息,这里是输出:

    Width of rectOne: 100
    Height of rectOne: 200
    Area of rectOne: 20000
    X Position of rectTwo: 23
    Y Position of rectTwo: 94
    X Position of rectTwo: 40
    Y Position of rectTwo: 72

    以下三个部分用上面的例子,在一个程序中来描述一个对象的生命周期。从中你将学会如何编写代码,在自己的程序中创建和使用对象。您还将了解当对象生命周期结束时,系统会清理对象。

    创建对象

    正如你所知道的,一个类会为对象提供蓝图,你可以使用类创建对象。CreateObjectDemo程序每一个语句都是创建对象并赋值给变量:

    Point originOne = new Point(23, 94);
    Rectangle rectOne = new Rectangle(originOne, 100, 200);
    Rectangle rectTwo = new Rectangle(50, 100);

    第一行创建了Pointer类的对象,第二行和第三行分别创建了Rectangle 类的对象。 每一个语句都有三个部分(细节如下):

    1.声明:数据类型和变量名

    2.实例化:new关键字是java操作符,用来创建对象。

    3.初始化:new操作符紧跟着一个构造方法,用来初始化对象。

     

    声明一个指向对象的变量

    之前,我们学到,声明一个变量,会这么写:

    type name;

    这个通知编译器,你将会使用name指向类型为type的数据。如果是原生类型的变量,这个声明会为变量分配合适大小的内存。

    你也可以在单行声明一个引用变量,例如:

    Point originOne;

    如果这么声明originOne,它的值在创建一个对象并赋值给它之前,是不确定的。声明一个引用变量不会创建一个对象。创建对象,需要使用new操作符。我们必须在代码中使用originOne之前,必须赋值一个对象给它。否则,编译器会报错。

    一个变量如果在没有指向任何对象的状态下,可以详解如下(变量名,originOne, 加一个没有指向其他对象的引用):

    originOne is null.

    实例化一个类

    new操作符实例化类的对象,分配内存,返回内存的引用。new操作符也调用类的构造方法。

    注意:实例化类意味着创建一个对象,当你创建一个对象是,你就是创建了一个类的实例,这就是实例化一个类。

    new操作符要求一个独立,后缀的参数:一个构造方法的调用,构造方法的名字提供对应类的实例化。

    new操作符返回创建的对象引用,这个引用用于赋值给合适类型的变量,例如:

    
    
    Point originOne = new Point(23, 94);
    
    

    new操作符返回的引用未必一定要赋值给一个变量,它也可以直接在表达式使用。例如:

    int height = new Rectangle().height;

    初始化对象

    这里是Point类的代码:

    public class Point {
        public int x = 0;
        public int y = 0;
        //constructor
        public Point(int a, int b) {
            x = a;
            y = b;
        }
    }

    这个类只有一个构造方法。你可以看出它是一个构造方法,因为它的声明使用的名字和类名一样,而且没有返回值。Point类的构造方法有两个整形参数,就像代码的声明 (int a, int b)。跟着的语句使用23和94作为参数的值:

    Point originOne = new Point(23, 94);

    语句的执行结果,可以以下图来详解:

    originOne now points to a Point object.

    这里是Rectangle类的代码,它有四个构造方法:

    public class Rectangle {
        public int width = 0;
        public int height = 0;
        public Point origin;
    
        // four constructors
        public Rectangle() {
            origin = new Point(0, 0);
        }
        public Rectangle(Point p) {
            origin = p;
        }
        public Rectangle(int w, int h) {
            origin = new Point(0, 0);
            width = w;
            height = h;
        }
        public Rectangle(Point p, int w, int h) {
            origin = p;
            width = w;
            height = h;
        }
    
        // a method for moving the rectangle
        public void move(int x, int y) {
            origin.x = x;
            origin.y = y;
        }
    
        // a method for computing the area 
        // of the rectangle
        public int getArea() {
            return width * height;
        }
    }

    每个构造方法都会让你提供长方形的长度和宽度的初始值,参数是原生类型和引用类型都有。如果一个类有多少构造方法,他们必须有不同的签名。java编译器通过参数的个数和类型,区别构造方法。当java编译器遇到下面的代码,它知道要调用参数为Pointer并紧跟两个整数的Pointer类的构造方法:

    Rectangle rectOne = new Rectangle(originOne, 100, 200);

    这个构造方法的调用,初始化rectOne 为originOne。同样的,构造方法会把宽度设置为100,高度设置为200.现在这里有两个引用指向同一个Point对象----一个对象可以被多个引用指向,就像下图显示:

    Now the rectangle's origin variable also points to the Point.

    下面的代码调用Rectangle类参数为两个整数类型的构造方法,它会提供width和height的初始化值。如果检查构造方法的代码,你会看到里面会创建一个Point对象,属性x和y初始化为0:

    Rectangle rectTwo = new Rectangle(50, 100);

    下面的语句,Rectanglez构造方法没有任何参数,它称之为无参构造方法:

    Rectangle rect = new Rectangle();

    所有类至少有一个构造方法,如果类没有显式声明一个构造方法,java编译器会自动提供一个构造方法,称之为默认构造方法。默认构造方法调用父类的无参构造方法。如果父类没有构造法方法(Object类有一个构造方法),编译器会拒绝这个程序。

    使用对象

    当你创建对象后,你极有可能用它来做一些事情,你可能使用它的成员变量的值,改变它的成员变量的值,或者是调用它的方法完成某个任务。

    引用对象的成员变量

    对象成员变量是通过名字访问的,你必须使用一个明确的名字。

    你可以在类里使用一个简单的名字。例如,我们可以在Rectangle类添加一个语句,输出长度和高度:

    System.out.println("Width and height are: " + width + ", " + height);

    这个场景下,widthheight就是简单的名字。

    在代码中,在类以外访问必须使用类的引用或者表达式,紧着一个.操作符,紧着一个简单的成员变量名,例如:

    objectReference.fieldName

    例子,CreateObjectDemo类的代码,是在Rectangle的外层,所以要引用对象名为rectOneorigin, width, and height这些成员变量,CreateObjectDemo类必须分别使用rectOne.origin, rectOne.width,rectOne.height.这个程序使用下面的名字显示rectOne对象的宽度和高度:

    System.out.println("Width of rectOne: "
                       + rectOne.width);
    System.out.println("Height of rectOne: "
                       + rectOne.height);

    的在CreateObjectDemo类中的代码尝试使用简单的名称widthheight是没有任何意义 - 这些成员变量只存在对应的对象,这会导致 一个编译错误。

    等下这个程序会使用相同的代码,显示rectTwo的信息。同一类型的多个对象,本身都有自己成员变量的拷贝。所以每一个Rectangle对象都有自己的成员变量origin, width, height.当你通过对象引用访问实例的成员变量时,你引用的就是对应的对象的成员变量了。两个对象rectOnerectTwo在CreateObjectDemo程序中都有自己的origin, width, height成员变量。

    为了访问成员变量,你可以使用一个对象的命令引用,就像之前的例子,或者使用一个表达式返回一个对象引用。重新调用new操作符返回一个对象的引用。回想一下,new操作符会返回一个对象引用。所以你可以new返回的值,访问对象的成员变量:

    int height = new Rectangle().height;

    这个语句创建了Rectangle对象并理解获取它的高度。在本质上,这个语句获取了一个Rectangle的默认高度,但是这个语句执行后,这个程序没有任何 引用指向了创建的Rectangle对象。因为程序没有存储该引用。对象没有被引用,它的资源会被java虚拟机回收。

    调用对象的方法

    你可以通过对象引用调用对象的方法。你在对象引用添加.操作符,再追加方法的简明名字。当然,你需要在闭合的小括号内提供方法的参数。如果方法不要求任何参数,使用空的小括号。

    objectReference.methodName(argumentList);
    or:
    objectReference.methodName();

    Rectangle类有两个方法:getArea()计算长方形的面积,move()修改长方形的大小,CreateObjectDemo代码调用了以下两个方法:

    System.out.println("Area of rectOne: " + rectOne.getArea());
    ...
    rectTwo.move(40, 72);

    第一个语句调用rectOnegetArea()方法,并显示结果。第二个语句调整rectTwo的大小,move()方法将对象的origin.xorigin.y重新赋新值。

    和实例成员变量一样,objectReference必须是一个对象引用。您可以使用一个变量的名字,但你也可以使用任何返回一个对象引用的表达式。new操作符返回一个对象的引用,这样你就可以使用new的返回值调用新对象的方法:

    new Rectangle(100, 50).getArea()

    表达式new Rectangle(100, 50)返回一个对象引用,它指向了Rectangle对象。如图所示,你可以使用.符号来调用新的Rectangle的getArea()方法计算新创建的长方形形的面积。

    一些方法,如getArea(), 返回一个值。针对方法的返回值,你可以在表达式中使用方法调用,把返回值赋值给变量,使用它来做条件判断,循环控制。下面的代码,把getArea()的返回值赋值给变量areaOfRectangle:

    int areaOfRectangle = new Rectangle(100, 50).getArea();

    记住,对一个对象调用方法,就像给对象发送消息。这个场景下,构造方法返回的rectangle对象引用并调用getArea()

    垃圾回收器

    一些面向对象的语言需要你跟踪创建的所有对象,当他们不需要时,您要显式地销毁他们时。显示管理内存是繁琐并容易出错的, Java平台允许您创建尽可能多的想要的对象(数量有限由你的系统的处理能力决定),你不必担心什么时候销毁对象。 Java运行时中删除不再被使用的对象,这个过程被称为“垃圾回收。

    当对象没有任何引用时,它就符合垃圾收集器的回收对象了。引用一般保存在变量里,当变量离开了代码块的范围,就会销毁了。当然,你也可以把一个变量设置为null,显式删除一个对象引用。注意的是程序中,一个对象可以有多少引用,所有的引用删除了,这个对象才符合垃圾收集器的回收对象。

    Java运行时环境有一个垃圾收集器,周期性地释放不再被引用的对象的内存。垃圾收集器会自动运行,由它本身决定运行的正确时间。

  • 相关阅读:
    CSU 1505: 酷酷的单词【字符串】
    HDU 2036 改革春风吹满地【计算几何/叉乘求多边形面积】
    HDU 2034 人见人爱A-B【STL/set】
    HDU 2031 进制转换
    HDU 1020 Encoding【连续的计数器重置】
    HDU 1999 不可摸数【类似筛法求真因子和】
    动态规划总结
    CSU 1785: 又一道简单题
    CSU 1779: 错误的算法【矩阵/模拟】
    CSU 1777: 大还是小?【模拟/后导0】
  • 原文地址:https://www.cnblogs.com/ggjucheng/p/2793158.html
Copyright © 2020-2023  润新知