- 首先, 类的目的是抽象出一类事物共有的属性和行为,并用一定的语法格式来描述所抽象出的属性和行为。也即是说,类是一种用于创建具体实例(对象)的数据类型。
- static给予修饰的称作类变量,否则称作实例变量,同样,方法类型前面不加关键字static修饰的方法是实例方法,否则则是类方法 , 例如:
public class Demo{
int x; // 实例变量
static int y;//类变量
float max(float m , float n ){ //实例方法
....
}
static float min(float m , float n ){ //类方法
....
}
}
public class Demo{
int x; // 实例变量
static int y;//类变量
float max(float m , float n ){ //实例方法
....
}
static float min(float m , float n ){ //类方法
....
}
}
3. 明白实例变量和类变量的区别
1) 不同对象的实例变量互不相同:
一个类通过使用new运算符可以创建多个不同的对象,而这些对象将分配不同的成员变量,即分配给不同的对象的实例变量占有不同的内存空间。改变其中一个对象的实例变量不会影响其他的对象的变量。
2) 所有对象共享类变量
当类中存在类变量,当创建多个不同对象时,分配给这些对象的这个类变量占有相同的一处内存。改变其中一个会影响其他, 即说对象共享类变量。
3) 通过类名直接访问类变量
当java程序运行时,类的字节码文件被加载到内存,如果该类没有创建对象,类中的实例变量不会被分配内存。但是,类中的类变量,在该类被加载到内存时,就分配了相应的内存空间。如果该类创建对象,那么不同的对象的实例变量互不相同,即分配不同的内存空间,而类变量不在重新分配内存,所有的对象共享类变量,即所有的对象的类变量是相同的一处内存空间。
4. 实例方法和类方法的区别
1) 对象调用实例方法
当类的字节码文件被加载到内存时,类的实例方法不会被分配入口地址,只有该类创建对象后,类中的实例方法才分配入口地址,从而实例方法可以被类创建的任何对象调用执行。 的那个创建第一个对象时,类中的实例方法就分配了入口地址,当在创建对象是,不在分配入口地址。即方法的入口地址被所有对象共享,当所有的对象都不存在时,方法的入口地址才会被取消。
实例方法中不仅可以操作实例变量,也可以操作类变量。
2) 类名调用方法
对于类方法,在该类被加载到内存时,就分配了相应的入口地址,从而类方法不仅可以被类创建的任何对象调用执行,也可以直接通过类名调用。类方法的入口地址知道程序退出才被取消。需要注意的是,实例方法不能通过类名调用,只能有对象调用。
和实例方法不同的是,类方法不可以操作实例变量,这是因为在类创建对象之前,实例成员变量还没有分配内存。
/**
* @author 牧羊的伯格女皇
* date: 2015-10-12
*/
public class Lader {
private double upper; //上底
private double height; //高
public static double bottom; // 下底 类变量
public double getUpper() {
return upper;
}
public void setUpper(double upper) {
this.upper = upper;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public static double getBottom() { //类方法
return bottom;
}
public static void setBottom(double bottom) { // 类方法
Lader.bottom = bottom;
}
//求面积:
public double laderarea(){
return (bottom+upper)*height/2;
}
}
/**
* TestLader.java
* */
public class TestLader {
public static void main(String[] args) {
Lader laderOne = new Lader();
Lader laderTwo = new Lader();
Lader.bottom = 10; //Lader的字节码被加载到内存,通过类名直接访问类变量
System.out.println("通过类名直接访问类变量的值是: " + Lader.bottom ); // 10
laderOne.setHeight(10);
laderOne.setUpper(10);
double areaOne = laderOne.laderarea();
System.out.println("通过类名直接调用执行类方法得到梯形One下底的值: "+Lader.getBottom()); // 10
System.out.println("求得梯形One面积为: " + areaOne + "\n" ); // 100
laderTwo.setHeight(20);
laderTwo.setUpper(20);
Lader.setBottom(20); // 通过对象调用执行类方法
System.out.println("通过对象调用执行类方法得到的梯形Two下底的值: " + Lader.getBottom() );//20
double areaTwo = laderTwo.laderarea();
System.out.println("求得梯形Two面积为: " + areaTwo ); //400
}
}
/**
* @author 牧羊的伯格女皇
* date: 2015-10-12
*/
public class Lader {
private double upper; //上底
private double height; //高
public static double bottom; // 下底 类变量
public double getUpper() {
return upper;
}
public void setUpper(double upper) {
this.upper = upper;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public static double getBottom() { //类方法
return bottom;
}
public static void setBottom(double bottom) { // 类方法
Lader.bottom = bottom;
}
//求面积:
public double laderarea(){
return (bottom+upper)*height/2;
}
}
/**
* TestLader.java
* */
public class TestLader {
public static void main(String[] args) {
Lader laderOne = new Lader();
Lader laderTwo = new Lader();
Lader.bottom = 10; //Lader的字节码被加载到内存,通过类名直接访问类变量
System.out.println("通过类名直接访问类变量的值是: " + Lader.bottom ); // 10
laderOne.setHeight(10);
laderOne.setUpper(10);
double areaOne = laderOne.laderarea();
System.out.println("通过类名直接调用执行类方法得到梯形One下底的值: "+Lader.getBottom()); // 10
System.out.println("求得梯形One面积为: " + areaOne + "\n" ); // 100
laderTwo.setHeight(20);
laderTwo.setUpper(20);
Lader.setBottom(20); // 通过对象调用执行类方法
System.out.println("通过对象调用执行类方法得到的梯形Two下底的值: " + Lader.getBottom() );//20
double areaTwo = laderTwo.laderarea();
System.out.println("求得梯形Two面积为: " + areaTwo ); //400
}
}