Java对象和类

1. 对象和类

1.1 定义类和创建对象

面向对象程序设计(OOP)就是使用对象进行程序设计。使用一个通用类来定义同一类型的对象。类是一个模板,用来定义对象的数据域是什么以及方法是做什么的。

请添加图片描述
此图为UML类图,用来表示Circle类。
创建Circle类的代码如下:

class Circle{
    double r;
    Circle(){
        r = 1;
    }
    Circle(double newR){
        r = newR;
    }
    double getAre(){
        return r * r * Math.PI;
    }
    double getD(){
        return 2 * r;
    }
    void reSetR(double newR){
        r = newR;
    }
}

使用Circle类的代码如下:

public class Main{
    public static void main(String[] args){
        Circle circle1 = new Circle();
        System.out.println(circle1.r);
        System.out.println(circle1.getAre());
        Circle circle2 = new Circle(5);
        System.out.println(circle2.r);
        System.out.println(circle2.getD());
    }
}

1.2 构造方法

1.Circle类中的构造方法必须与所在类有相同的名字
2.构造方法没有返回值,也没有void
3.构造方法是创建一个对象时使用new操作符时所调用的。
构造方法可以重载(如Circle类中有两个相同的构造方法,但两者的签名不同)
4.方法有关键字,构造方法没有关键字,如:double getAre()和Circle(double newR)
5.Circle()构造方法称为无参构造方法
6.一个类可以不定义构造方法,系统会默认提供一个无参构造方法,这个构造方法称为默认构造方法

1.3 通过引用变量访问对象

1.3.1 创建

ClassName name = new ClassName();

这句话包括:
1.声明name为ClassName类
2.创建一个新的ClassName类
3.将新的ClassName类赋值给name

1.3.2 访问对象的数据和方法

创建一个对象后可以使用.来访问数据或方法
例如:
circle1.r表示访问circle1的数据r
circle1.getAre()表示访问circle1的方法getAre()

1.3.3 null值

class student{
	String name;
	int age;
	boolean sex;
	char x;
}

以上数据域未赋值,String默认值为null,int等数值类型默认值为0,boolean默认值为false,char默认值为 (一个空格)。

1.3.4 变量赋值给另一个变量

基本类型:

int i = 1;
int j = 2;
//赋值
i = j;

赋值前i和j各占据一个int的存储位置
赋值后i和j都等于2,占据的存储位置不变
对象类型:

Circle c1 = new Circle(5);
Circle c2 = new Circle(3);
//赋值
c1 = c2

对于Circle的对象c1,c2存的是引用,赋值后:
在这里插入图片描述
此时c1和c2指向同一个对象,c1之前指向的对象不再有用,此时它成为了垃圾,垃圾会占用内存空间,Java会检测垃圾并自动回收垃圾,这个过程称为垃圾回收。

2. Java库中的类

2.1 Date类

java.util.Date描述
+Date()创建一个Date对象
+toString返回字符串形式的当前时间
+getTime()返回1970.1.1至今流逝的毫秒数

+号表示public修饰符

java.util.Date date = new java.util.Date();
System.out.println(date.getTime());
System.out.println(date.toString());

输出

1648191707654
Fri Mar 25 15:01:47 CST 2022

2.2 Random类

java.util.Random描述
+Random()以当前时间作为种子创建一个新对象
+Random(seed)以特定值为种子创建一个新对象
+nextInt()返回一个随机Int值
+nextInt(n)返回一个0到n的随机int值
+nextLong()返回一个随机long值
+nextDouble()返回一个0.0到1.0的随机double值
+nextFloat()返回一个0.0到1.0的随机float值
+nextBoolean()返回一个随机的boolean值

创建一个Random对象时必须指定一个种子或使用默认种子,如果使用两个种子相同则会产生相同的数列

public class Main{
    public static void main(String[] args){
        Random random1 = new Random(3);
        for(int i = 0;i < 10;i++){
            System.out.print(random1.nextInt(100) + " ");
        }
        System.out.println();
        Random random2 = new Random(3);
        for(int i = 0;i < 10;i++){
            System.out.print(random2.nextInt(100) + " ");
        }
    }
}

输出为

34 60 10 81 28 2 49 64 59 61 
34 60 10 81 28 2 49 64 59 61

3.静态实例变量、常量和方法

3.1 实例变量

Circle类的r称为实例变量,实例变量是绑定到类中的某个特例的,不能被同一类的不同对象所共享,例如:

Circle circle1 = new Circle();
Circle circle2 = new Circle(5);

circle1和circle2中的r是不相关的,即改变circle1中的r不会影响到circle2中的r,反之亦然
如果想让一个类的所有实例共享数据,就要用到静态变量

3.2 静态变量

静态变量用static声明

class CircleWithStatic{
    double r;
    static int num = 0;
    CircleWithStatic(){
        r = 1;
        num++;
    }
    CircleWithStatic(double newR){
        r = newR;
        num++;
    }
    static int getNum(){
        return num;
    }
    double getAre(){
        return Math.PI * r * r;
    }
}

num为静态变量,所有CircleWithStatic对象共用一个num

public class Main{
    public static void main(String[] args){
        CircleWithStatic circle1 = new CircleWithStatic();
        System.out.println(circle1.getNum());
        CircleWithStatic circle2 = new CircleWithStatic();
        System.out.println(circle2.num);
    }
}

运行结果为

1
2

说明num是所有对象共用的int,因此一般使用
CircleWithStatic.num和CircleWithStatic.getNum()来代替circle2.num和circle1.getNum()
来增强代码的可读性
例如使用的Math.PI中的PI就是定义在Math中的常量

3.3 静态与实例关系

在同一个class中
实例方法
静态方法
错误代码:

public class A{
    int i = 5;
    static int j = 3;
    public static void main(String[] args){
        int k1 = i;
        int k2 = j;
        m1();
        m2();
    }
    public void m1(){
        System.out.println("Hello World!");
    }
    public static void m2(){
        System.out.println("Hello World!");
    }
}

在同一个class A中
其中i为实例变量,j为静态变量
静态方法main中k1访问了实例变量i,错误
静态方法main中k2访问了静态变量j,正确
静态方法main中调用了实例方法m1(),错误
静态方法main中调用了静态方法m2(),正确

正确代码1:

public class A{
    int i = 5;
    static int j = 3;
    public static void main(String[] args){
        A a = new A();
        int k1 = a.i;
        int k2 = j;
        a.m1();
        m2();
    }
    public void m1(){
        System.out.println("Hello World!");
    }
    public static void m2(){
        System.out.println("Hello World!");
    }
}

正确代码2:

public class A{
    static int i = 5;
    static int j = 3;
    public static void main(String[] args){
        int k1 = i;
        int k2 = j;
        m1();
        m2();
    }
    public static void m1(){
        System.out.println("Hello World!");
    }
    public static void m2(){
        System.out.println("Hello World!");
    }
}

4. 可见性修饰符

4.1 public

一个Java源文件中只能有一个public class Name,表示公共接口。可以有很多class Name,有几个class就会编译出几个文件。一个public class表示一个源文件
在类、方法和数据域前使用public表示它们可以被其他类访问

4.2 private

在类、方法和数据域前使用private表示它们仅可以在自己的public class 中被访问。
例如:

public class Main{
    public static void main(String[] args){
        m1();
        m2();
    }
    private static void m1(){
        System.out.println("Hello World!");
    }
    public static void m2(){
        System.out.println("Hello World!");
    }
}

此时m1()和m2()都可以被访问

public class Test{
    public static void main(String[] args){
        m1();
        m2();
    }
}

此时为另一个源文件,可以调用m2(),但不可以调用m1(),因为m1()是private私有的

4.3 数据域封装

将原本的CircleWithStatic改为如下NewCircleWithStatic

class NewCircleWithStatic{
    private double r;
    private static int num = 0;
    NewCircleWithStatic(){
        r = 1;
        num++;
    }
    NewCircleWithStatic(double newR){
        r = newR;
        num++;
    }
    static int getNum(){
        return num;
    }
    double getAre(){
        return Math.PI * r * r;
    }
    double reSetR(double newR){
		r = newR;
	}
}

新代码在
private double r;
private static int num = 0;
前各加了一个private,这样保证客户无法通过circle.r = ?和circle.num = ?来修改数据,无法篡改数据,如果客户试图访问r或num则会产生编译错误

5. 向方法传递对象参数

public class Main{
    public static void main(String[] args){
        Circle circle = new Circle();
        int n = 5;
        print(circle,n);
    }
    public static void print(Circle c,int time){
        for(int i = 0;i < time;i++){
            System.out.println(i + ":" + circle.r);
            circle.r += 1; 
        }
    }
}

对象参数的传递同数组传递一样,值传递。
在print函数中改变time值,不会影响main函数中n的值
在print函数中改变circle.r的值,会影响circle.r的值

6. 不可变对象和不可变类

如果给一个对象加上修饰符private,并且不设置Reset方法,那么这个对象就称为不可变对象。
如果一个类的所有数据域都被private修饰,并且没有Reset方法,那么这个类就称为不可变类。

7. this类

在类内部调用类里的数据,要在数据前加this.
但通常可以被省略
例如:

class Circle{
    double r;
    Circle(){
        this.r = 1;
    }
    Circle(double newR){
        this.r = newR;
    }
    double getAre(){
        return this.r * this.r * Math.PI;
    }
    double getD(){
        return 2 * this.r;
    }
    void reSetR(double newR){
        this.r = newR;
    }
}

不可省略的情况

class Circle{
    double r;
    Circle(){
        r = 1;
    }
    Circle(double r){
        this.r = r;
    }
    double getAre(){
        return r * r * Math.PI;
    }
    double getD(){
        return 2 * r;
    }
    void reSetR(double r){
        this.r = r;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值