一、类和对象的概念
简单来说,类是一种模板,由属性和方法所组成,而对象就是类的一个实例,有特有的属性。
二、类的格式
一个类是由一些属性和方法构成,而且类名必须与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一个对象时,会在堆内存分配空间存放对象的属性,在栈内存存放一个引用变量(也即对象名),这个变量指向对应的堆内存。
同一个对象可以被多个引用变量所指向,这些引用变量都可以管理对象的属性。如下面这个例子。
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进一步说明。
五、访问权限
java的访问权限分为4类:
- friendly(默认):在包内都可见
- public:对所有类都可见
- protected:包内和其他包的子类(父类在当前包的情况下)都可见。(在子类的main方法里不可见,对成员变量和成员函数可见)
-
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
}
}