[Java] 对象和类

1 定义类,创建对象

创建对象的语法:
ClassName objectRefVar = new ClassName();

类的3种组织形式:

  • 将两个类放在同一个.java 文件中
// 文件:TestSimpleCircle.java
public class TestSimpleCircle {
    //…
}
class SimpleCircle {
    //…
}

此文件由Java Compiler编译,生成两个类文件: TestSimpleCircle.classSimpleCircle.class
如果两个类放到一个文件中,那么,文件中只有一个类可以为public class, 与此同时,文件名必须和公有类同名,例如目前的文件名为TestSimpleCircle.java

  • 合并两个类
public class SimpleCircle {
    /** Main method */
    public static void main(String[] args) {
        // Create a circle with radius 1
        SimpleCircle circle1 = new SimpleCircle();
        System.out.println("The area of the circle of radius " + circle1.radius + " is " + circle1.getArea());

        // Create a circle with radius 25
        SimpleCircle circle2 = new SimpleCircle(25);
        System.out.println("The area of the circle of radius " + circle2.radius + " is " + circle2.getArea());

        // Create a circle with radius 125
        SimpleCircle circle3 = new SimpleCircle(125);
        System.out.println("The area of the circle of radius " + circle3.radius + " is " + circle3.getArea());

        // Modify circle radius
        circle2.radius = 100;
        System.out.println("The area of the circle of radius " + circle2.radius + " is " + circle2.getArea());
    }
    // 下面的代码其实是另一个类,class 和 花括号都省略了。
    double radius;
    /** Construct a circle with radius 1 */
    SimpleCircle() {
        radius = 1;
    }
    /** Construct a circle with a specified radius */
    SimpleCircle(double newRadius) {
        radius = newRadius;
    }
    /** Return the area of this circle */
    double getArea() {
        return radius * radius * Math.PI;
    }

    /** Return the perimeter of this circle */
    double getPerimeter() {
        return 2 * radius * Math.PI;
    }

    /** Set a new radius for this circle */
    void setRadius(double newRadius) {
        radius = newRadius;
    }
}

这种写法,将两个不同名的类合并成了一个类,看起来就是一个。
如果要测试某个类,可以在类中加一个main方法就可以测试。

  • 两个类各自放在不同的文件中
    不包含main的class将它的所有方法定义为public, 以便其他类调用。

2 构造函数

创建对象时,使用new操作符调用构造函数。
没有参数的构造函数叫做无参构造函数(no-arg 或 no-argument constructor) 例如Circle()

可以定义没有构造函数的类,这种情况下,类中会隐式定义一个方法内容为空的public 无参构造函数。此构造函数称为默认构造函数仅当类中没有显式定义构造函数时被自动提供。

3 使用引用变量访问对象

匿名对象: 创建对象,但是并不将这个对象赋给变量

new Circle();
System.out.println("Area is " + new Circle(5).getArea());

4 使用Java库中的类

5 静态变量、常量和方法

// 声明静态变量
static int numberOfObjects;
// 定义静态方法
static int getNumberObjects() {
    return numberOfObjects;
}
实例方法:
  • 能够调用实例方法
  • 能够访问实例数据域
  • 能够调用静态方法
  • 能够访问静态数据域
静态方法:
  • 不能 调用实例方法
  • 不能 访问实例数据域
  • 能够调用静态方法
  • 能够访问静态数据域

因为main方法是静态的,所以可从类直接调用。

6 可见性修饰符

Java用包(package) 组织类,程序的第一行语句是:

package packageName;

如果定义类时,没有包语句, 那么它就在默认包(default package)里。Java 建议将类放在包中,不要放在默认包中。
可见性修饰符有3种:public, protected, private
使用可见性修饰符public 用于类、方法和数据域以表示可以从其他任何类访问他们。
如果没有使用可见性修饰符,那么,类、方法以及数据域默认可以被同一包中的任意类类访问,这称为 package-private 或 package-access。
private修饰符使得方法和数据域只能从自己的类内部访问。
protected关键字在11.4 继承中说明,这章没有。

扫描二维码关注公众号,回复: 1781120 查看本文章

以下是两个包,3个类,从中可以看出,使用public, private, 和default情况下对访问的限制:

// Package p1
package p1;
public class C1 {
    public int x;
    int y;
    private int z;
    public void m1() {
    }
    void m2() {
    }
    private void m3() {
    }
}
// Package p1
package p1;
public class C2 {
    void aMethod() {
        C1 o = new C1();
        能访问 o.x;
        能访问 o.y;
        !不能访问 o.z;  // 因为是private
        能调用 o.m1();
        能调用 o.m2();
        !不能调用 o.m3();  // 因为是private
    }
}
// Package P2
package p2;
public class C3 {
    void aMethod() {
        C1 o = new C1();
        能访问 o.x;
        !不能访问 o.y;  // 因为是default,且不同包
        !不能访问 o.z;  // 因为是private
        能调用 o.m1();
        !不能调用 o.m2();  // 因为是default,且不同包
        !不能调用 o.m3();  // 因为是private
    }
}

如果一个类没有定义为public, 那么它只能在同一个包内被访问,下面的例子,C2可访问C1,但是C3不能访问C1

package p1;
class C1 {
...
}
package p1;
public class C2 {
    能访问 C1
}
package p2;
public class C3 {
    不能访问 C1;
    能访问 C2;
}

如果对象被定义在自己的类内部,那么这个对象可以访问它的私有成员。

私有构造函数

例如对于Math类,因为它的所有数据域和方法都是静态的,为了阻止用户创建Math类的实例,使用私有构造函数(private constructor) , 这样用户就没法创建类的实例了。
java.lang.Math的构造函数定义为:

private Math() {
}

7 数据域封装

数据域封装,即指将数据域声明为private, 同C++的概念,使得程序易于维护,防止随意修改数据域。

为了从类外部读取和更新私有的数据域,通常为私有数据域提供两个方法:gettersetter, (getter又叫accessor, setter又叫mutator):

public returnType getPropertyName()  // getter

如果returnType为boolean,那么getter方法依照惯例定义成如下的形式:

public boolean isPropertyName()   
public void setPropertyName(dataType propertyValue)  // setter

8 传递对象给方法

实际上传递的是对象的引用。

9 由对象构成的数组

创建对象数组并初始化:

// 创建对象数组
Circle[] circleArray = new Circle[10];
// 初始化
for (int i = 0; i < circleArray.length; i++) {
    circleArray[i] = new Circle();
}

对象数组实际上是引用变量的数组。

10 不可变的对象和类

如果对象创建之后,无法修改数据域,这样的对象称为不可变对象,对应的类称为不可变类。
不可变类满足以下3个条件:
1. 所有数据域私有
2. 不能有可以改变数据域的方法
3. 不能有返回数据域引用的方法

下面的例子,虽然满足前两个条件,但不满足第3个条件,因此这个类不属于不可变类:

public class Student {
    private int id;
    private String name;
    private java.util.Date dateCreated;

    public Student(int ssn, String newName) {
        id = ssn;
        name = newName;
        dateCreated = new java.util.Date();
    }
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public java.util.Date getDateCreated() {
        return dateCreated;
    }
}
public class Test {
    public static void main(String[] args) {
        Student student = new Student(111223333, "John");
        java.util.Date dateCreated = student.getDateCreated();
        dateCreated.setTime(200000); // dateCreated 域发生了改变!
    }
}

11 变量作用域

声明findArea()radius的顺序可任意:

public class Circle {
    public double findArea() {
        return radius * radius * Math.PI;
    }
    private double radius = 1;
}

i必须在j之前声明,因为j的初值依赖于i

public class F {
    private int i ;
    private int j = i + 1;
}

12 this引用

this即指向对象自身, 如果访问静态变量,使用ClassName.StaticVariable,否则用this
使用this调用构造函数的一个例子:

public class Circle {
    private double radius;
    public Circle(double radius) {
        this.radius = radius; // 使用this引用类自身被隐藏的radius
    } 
    public Circle() {
        this(1.0); // 使用this调用上一个构造函数
    } 
...
}

[1] Introduction to java Programming 10th. Chapter 9 Objects and Classes

猜你喜欢

转载自blog.csdn.net/ftell/article/details/80508697