L的java学习笔记——对象与类

时间:2023-02-24 08:31:13

一、类和对象的概念

简单来说,类是一种模板,由属性和方法所组成,而对象就是类的一个实例,有特有的属性。

二、类的格式

一个类是由一些属性和方法构成,而且类名必须与java文件名一样,基本框架如下。

public class 类名 {
    //属性+方法;

    public static void main(String[] args) {
        // 程序入口
    }
}

举个实例来辅助说明。

public class Person {
    //属性
    private int weight;
    private int height;
    private int age;
    //方法
    public void printinfor() {
        System.out.println("weight:"+weight+"\nheight:"+height+"\nage:"+age);
    }
    public static void main(String[] args) {
        // 程序入口

    }
}

三、对象的创建

有了一个具体的类后,就可以用这个类来创建出一些对象。

  • 基本格式
    类名 对象名=new 类名();
Person Zhangsan = new Person();
  • 方法调用
    对象调用方法的格式:
    对象名.方法;
Zhangsan.printinfor();
  • 初始化和构造方法
    创建了一个对象后,我们发现这个Zhangsan的对象的height、weight、age好像都没有赋初始值。我们先来打印一下当前结果。
weight:0
height:0
age:0

我们发现它们都被赋成0。当java自己初始化时,int类型变量会赋值为0,float类型变量会赋值为0.0,String变量会赋null(因为String定义的是一个对象)。
那如何人为的给这些属性赋值呢?这时就用到了构造方法。
构造方法基本格式:
public 类名(有参或无参){
}

public Person() {

    }

如果类里面不写构造方法,java会自动调用无参的构造方法(虽然这个构造方法什么都不干),有参的形式如下。

public Person(int w,int h,int a) {
        this.weight=w;
        this.height=h;
        this.age=a;
    }

或
public Person(int weight,int height) {
        this.weight=weight;
        this.height=height;
    }

括号里的参数个数可以小于或等于属性里变量个数·,并且括号的参数名可以与属性里的变量名相同(this指的是当前对象)。一个类里可以有多个构造方法,在创建对象可以根据需要赋对应构造方法的参数的初始值(如果类里含有有参的构造方法,不含有无参的构造方法,在创建对象时java不会自动提供无参构造方法),如下。

public class Person {
    //属性
    private int weight;
    private int height;
    private int age;
    //方法
    public Person(int weight,int height,int age) {
        this.weight=weight;
        this.height=height;
        this.age=age;
    }
    public Person(int weight,int height) {
        this.weight=weight;
        this.height=height;
    }
    public void printinfor() {
        System.out.println("weight:"+weight+"\nheight:"+height+"\nage:"+age);
    }
    public static void main(String[] args) {
        // 程序入口
        Person Zhangsan=new Person();//报错:The constructor Person() is undefined
        Person Lisi=new Person(48,176); //正确 weight=48,height=176,age=0;
        Person Liuwu=new Person(54,184,21);//正确 weight=54,height=184,age=21;

    }
}

四、对象的引用

java的内存空间分成四部分:
1、栈区(stacksegment)—由编译器自动分配释放,存放函数的参数值,局部变量的值等,具体方法执行结束之后,系统自动释放JVM内存资源
2、堆区(heapsegment)—一般由程序员分配释放,存放由new创建的对象和数组,jvm不定时查看这个对象,如果没有引用指向这个对象就回收
3、静态区(datasegment)—存放全局变量,静态变量和字符串常量,不释放
4、代码区(codesegment)—存放程序中方法的二进制代码,而且是多个对象共享一个代码空间区域
new一个对象时,会在堆内存分配空间存放对象的属性,在栈内存存放一个引用变量(也即对象名),这个变量指向对应的堆内存。
L的java学习笔记——对象与类
同一个对象可以被多个引用变量所指向,这些引用变量都可以管理对象的属性。如下面这个例子。

public class Person {
    //属性
    private int weight;
    private int height;
    public int age;
    //方法
    public Person(int weight,int height,int age) {
        this.weight=weight;
        this.height=height;
        this.age=age;
    }

    public void printinfor() {
        System.out.println("weight:"+weight+"\nheight:"+height+"\nage:"+age);
    }
    public static void main(String[] args) {
        // 程序入口
        Person PerManager1=new Person(45,175,20);
        Person PerManager2=PerManager1;
        PerManager2.age=18;
        PerManager1.printinfor();

    }
}

可以看到利用PerManager2修改age后,PerManager1的age也随之修改,说明PerManager1和PerManager2管理的是同一个对象。可以通过调试查看它们的id进一步说明。L的java学习笔记——对象与类
L的java学习笔记——对象与类

五、访问权限

java的访问权限分为4类:

  1. friendly(默认):在包内都可见
  2. public:对所有类都可见
  3. protected:包内和其他包的子类(父类在当前包的情况下)都可见。(在子类的main方法里不可见,对成员变量和成员函数可见)
  4. private:仅在类内可见。
    访问级别由大到小为:public、protected、friendly、private。
**package1:**
package package1;

public class classA {
    int friendly_variable;
    public int public_variable;
    protected int protected_variable;
    private int private_variable;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        classA test=new classA();
        test.friendly_variable=1; //正确
        test.public_variable=1; //正确
        test.private_variable=1; //正确
        test.protected_variable=1; //正确
    }

}

----------
package package1;

public class classB {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        classA test1=new classA();
        test1.friendly_variable=2; //正确
        test1.protected_variable=2; //正确
        test1.public_variable=2; //正确
        test1.private_variable=2; //The field classA.private_variable is not visible
    }

}
**package2:**
package package2;

import package1.classA;

public class classC extends classA{

    public void print() {
        int a=public_variable; //正确
        int b=protected_variable; //正确
        int c=private_variable; //The field classA.private_variable is not visible
        int d=friendly_variable; //The field classA.friendly_variable is not visible
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        classA test2=new classA();
        test2.public_variable=3; //正确
        test2.private_variable=3; //报错:The field classA.private_variable is not visible
        test2.friendly_variable=3; //报错:The field classA.friendly_variable is not visible
        test2.protected_variable=3; //报错:The field classA.protected_variable is not visible

    }

}