修饰符
前文见: 【新手Java】12.类与对象 Class and Object(1)
【对于Class的静态关键词】 在学习方法的时候,我们已经了解了关键词static 如果我们将static与方法(或变量)一起使用, 则该方法仅属于类定义,并且永远不会传递到该类的实例(即对象)上
在所有程序编译运行的过程中,变量都是由系统自动分配内存进行存储的。
在这个存储过程中,static所修饰的变量(也就是静态变量),它所被分配的空间是一直伴随程序运行的,空间将会保持到程序的结束关闭,才会被释放。
换句话说:程序运行时,系统分配给静态变量的内存是一直存在的,除非程序被终止。
根据这一点来看,假若在定义一个类的过程中,定义了一个static修饰的变量,那么这个类在被加载的同时,被static修饰的变量就存在于内存当中了,这样一来就独立于该类的所有对象,被该类所有对象共享,将对象相关的变成了类相关,所以静态变量也可以称之为类变量。
假设一个类中某个属性被static所修饰,那么就可以通过"类名.属性名"来访问
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享 用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象时,不生成static变量的副本,而是类的所有实例共享同一个static变量
也就是说,static修饰的成员变量和成员方法可以看作是对于“全局”的,它们会被所有的类的实例所共用 用访问器来举例:若一个变量不是静态类的,那么我们想要获取这个变量的话就必须指定是哪个对象实例的“这个变量”
比如我们Car类实例了一个p1,我们想知道p1的颜色,就必须用访问器指定获得"p1"的"Color" 而用static修饰的变量,它是“属于类的类变量”,我们只需要指定这个类就可以获得它 比如我们的Car全是红旗牌子的,那么我们就可以把“红旗牌”设置为static,之后想知道该Car类的牌子只需要指定Car类即可,不需要细化到某个具体的实例
可以参考 https://blog.csdn.net/hxc1314157/article/details/78836220
【Java中的修饰符】 修饰符改变变量、方法和类的含义,有两种类型的修饰符 访问修饰符 Access Modifiers :设置对变量,方法,类或包的访问级别 非访问修饰符 Non-Access Modifiers:以其他(与访问无关的)方式设置变量、方法、类或包
访问修饰符 Access Modifiers 这里有四种访问修饰符(实际上是三种) public:使变量、方法、类或包在文件中任何地方被访问以及使用 private:使变量或方法只能在定义它的类中访问 Protected:使变量,方法或类只能在包或派生子类(继承)中访问 :没有特意去使用修饰符,默认值使变量、方法或类只能在包内访问(但子类不能访问)
知道何时使用这些修饰符将取决于类的要求,不过我们有以下几点经验: 1.大部分的类Class是public 2.大多数属性都是private 3.方法视目的和使用情况而定
个人理解,访问修饰符很多时候就像一种标记:标记哪些数据是可以被直接访问的,而哪些不会。事实上我们可以把所有的参数都设置为Public,然后再使用过程中再自己判断这个操作会不会误改变一些“我们本不应该修改的数值”(安全性)。但是使用了访问修饰符,我们就可以在定义参数的时候直接设置它们可被访问的范围,提高了安全性,也让后续操作更方便
比如在我们之前所述的Car类中,我们可以设置几个参数
private intnumberOfDoors;
private String colour;
private char motorType;
这并不意味着我们没办法在外部修改它们的数值,我们这么做是因为我们不希望用户直接去修改它们,用户需要使用我们指定的方法来设置/修改它们(这就是更改器的作用了) 通常,我们想精确地控制用户访问类属性的方式;很多时候将变量设为只读是有意义的。
**非访问修饰符 Non-Access Modifiers ** **static:**使变量或方法成为类的成员,而不是类的实例的成员(即,类变量,而不是对象变量) static variable/class variable 和 instance vatiable 最重要的是,static variable 并非某个实例的变量,而是属于这个类的变量。这个变量的值是随着类改变的,每次调用它的值就是它本身,而不是它的副本
**final :**使变量为常量且不能更改 还有其它的,比如 abstractand 和 synchronized
当我们确定一个变量或方法只存在一个副本时,或者当我们希望类控制该变量或方法(而不是控制它的对象)时,我们使用static 我们在生成代码中反复使用的常量变量时使用final
例子 1.对于static,一个最主要的例子就是main方法
public static void main(String[] args) { }
我们在这里使用static,因为我们只需要一个main()方法。使用static可以保证无论用户对包含main()的类做什么,都是这样
private static int lastCarReg= 1000;
public Car(){
lastCarReg++ ; //每次生产一个Car,我们就把lastCarReg增加1,lastCarReg总数是随类变化的
carReg = lastCarReg ; //每辆车的carReg是独立的
}
完全版的更新后的Car()
public Car()
{
numberOfDoors = 4;
colour = "Black";
motorType = 'I';
lastCarReg++; //increase the value
carReg = lastCarReg; // assign that value to the reg of this Car instance
}
public Car(int numberOfDoors, String colour, char motorType)
{
this.numberOfDoors = numberOfDoors;
this.colour = colour;
this.motorType = motorType;
lastCarReg++;
carReg = lastCarReg;
}
关键词与对象
【this操作符】 有的时候,我们希望能够继续使用相同的变量名,但是,如果我们为参数选择的名称与为属性选择的名称相同,则会出现编译器错误 但是,如果我们在Java中使用特殊的this关键字,则可以区分作为参数传递的变量和属于类实例的变量
比如我们现在想要设置Car中一些参数的数值,我们就可以利用this关键字,从而不需要再取名字
public Car(int numberOfDoors, String colour,char motorType)
{
this.numberOfDoors = numberOfDoors; //使某个实例的numberOfdoors设置为该方法的传入值
this.colour = colour;
this.motorType = motorType;
}
【对象类 Object class 】 在Java中,每个类实际上都是非常重要的类的子类,这个“非常重要的类”就是Object类 Object类具有许多方法,这些方法可用于所有其他类
比如,在对象应用程序编程接口(API)中,toString()被描述为“返回此对象的字符串表示形式”的方法 在类中重写toString()方法以打印出与该类相关的所有信息是一种很好的做法。
之前我们用来打印的方法
public void printCarDetails()
{
String details = "Number of doors: " + numberOfDoors;
details += "\nColour: " + colour;
details += "\nMotor Type: " + motorType;
details += "Car Reg: " + carReg;
System.out.println(details);
}
修改后的代码
public String toString()
{
String details = "Number of doors: " + numberOfDoors;
details += "\nColour: " + colour;
details += "\nMotor Type: " + motorType;
details += "Car Reg: " + carReg;
return details;
}
【类和对象的总结】 1.可以将类视为模板。该模板可以是更通用的东西的蓝图 2.类的主要组件是: ?类名 ?属性,也称为实例变量 ?构造函数 ?访问器方法(也称为Getter方法) ?更改器方法(也称为Setter方法) ?以方法作为形式的功能 3.每个类都应该有一个默认构造函数和一个通用构造函数,在创建类的对象时,我们可以使用默认构造函数和通用构造函数 4.Accessors和mutator方法用于获取和设置类中的不同属性 5.访问修饰符-设置对变量,方法,类或包的访问级别 非访问修饰符-以其他(与访问无关)的方式更改变量,方法,类或包 6.Java中的this关键词可用于区分作为参数传递的变量和属于类实例的变量 7.在所有类中重写toString()方法以打印出与该类相关的所有信息是一种很好的做法 8.相关class之间的调用,需要它们在同一目录下
【之前提到的实例代码完整版】 Car:
public class Car
{
//Attributes
private int numberOfDoors;
private String colour;
private char motorType; //I = ICE, E = Electric F = fuelcell
private int carReg;
private static int lastCarReg = 1000;
//Constructors
//Default Constructor
public Car()
{
numberOfDoors = 4;
colour = "Black";
motorType = 'I';
lastCarReg++; //increase the value
carReg = lastCarReg; // assign that value to the reg of this Car instance
}
public Car(int numberOfDoors, String colour, char motorType)
{
this.numberOfDoors = numberOfDoors;
this.colour = colour;
this.motorType = motorType;
lastCarReg++;
carReg = lastCarReg;
}
public Car(int doors)
{
numberOfDoors = doors;
colour = "Black";
motorType = 'I';
}
//Getter methods
//get the colour
public String getColour()
{
return colour;
}
public int getDoors()
{
return numberOfDoors;
}
public char getMotorType()
{
return motorType;
}
public int getReg()
{
return carReg;
}
//Setter Methods
public void setDoors(int num)
{
numberOfDoors = num;
}
public void setColour(String col)
{
if(col.equals("Red") || col.equals("Green")){
colour = col;
}
}
//Functionality
public void printCarDetails()
{
String details = "Number of doors: " + numberOfDoors;
details += "\nColour: " + colour;
details += "\nMotor Type: " + motorType;
details += "Car Reg: " + carReg;
System.out.println(details);
}
public String toString()
{
String details = "Number of doors: " + numberOfDoors;
details += "\nColour: " + colour;
details += "\nMotor Type: " + motorType;
details += "Car Reg: " + carReg;
return details;
}
/*
public Car(int numberOfDoors, String colour,char motorType)
{
this.numberOfDoors = numberOfDoors;
this.colour = colour;
this.motorType = motorType;
}
public void setColour(String colour)
{
this.colour = colour;
}
*/
}
testCar:
public class TestCar{
public static void main(String args[]){
//Create a Car instance by calling the default constructor
Car c1 = new Car();
//Create another Car instance by calling our general constructor with 3 parameters
Car c2 = new Car(5,"red",'E');
Car c3 = new Car(16);
//Call printCarDetails method on each car
c1.printCarDetails();
c2.printCarDetails();
c3.printCarDetails();
System.out.println("Colours:");
System.out.println("The colour of Car C1 : " + c1.getColour());
System.out.println("The colour of Car C2 : " + c2.getColour());
System.out.println("The colour of Car C3 : " + c3.getColour());
c1.setColour("Green");
c3.setDoors(4);
c1.printCarDetails();
c3.printCarDetails();
System.out.println(c1.toString());
}
}
|