好长,有空我会用主副标题优化一下结构
类的概述
【概述】
在之前的课程中,我们看到了不同的内置类。这些类包括Scanner类和String类,以及一些原始数据类型的类,例如Integerand Double,Integer.parseInt(,Double.parseDouble()
【原始类型 Primitive types】
Java中有八大原始数据,为int,byte,short,float,double,Boolean,char和long
当我们声明这些原始类型的变量时,将分配固定大小的内存来保存要存储的值,每种类型分配的固定内存大小是不同的
简而言之,就是
原始数据类型的大小和灵活性都受到限制
【内置类】
数组 Array
数组是一种扩展原始数据类型的强大方法————它使我们可以在单个变量名下收集相同类型的变量,而我们也可以制作任意长度的数组
但即使是数组,它们也只能为我们做什么对应的事情,不能做超出它规则范围的事情
字符串 Strings
字符串是引用类型 reference type的一个例子
声明后,直到初始化的时候,才会给字符串分配内存
字符串类型比数组更强大,因为它可以容纳任何大小的值,字符串提供了可以与"值"交互的方法,如String.length()
这些(Scanner, String, Integer)是Java内置的一些类,我们还可以创建java类来执行特定的用户定义任务
【用户定义类 User Defined Class】
类是一类对象的定义,这些对象都具有相同的行为和相同类型的属性
我们可以把类视作一种模板
我们拿一辆车举例,对所有车辆,它们一般都有:
特定类型的电机、有颜色、有一定数量的门等等
除了拥有属性,每个类还可以执行某些用户自定的任务,比如上述的车:
我们既可以封装汽车的描述,也可以编码与汽车有关的功能
我们可以编写以捕获汽车属性和功能的代码称为类 class
另外,我们也可以使用其他对象作为属性
【类的组成】
1.类的名字 A class name
写法上有约定俗成的:类名应以大写字母开头,并且是一个名词
2.属性,实例变量 Attributes
这些变量会在类的内部用于保存值,另外其他对象也可以作为属性
3.构造器 Constructor(s)
应该始终有一个默认构造函数。这种类型的构造函数没有输入参数。如果没有提供,JVM将自动提供一个
构造器的名字和类的名字是一样的
4.Getters方法(也称为访问器 Accessors)
这些是用户定义的方法,用于返回类中的那些属性值
5.更改器 Setters(也称为 Mutators)
设置与更改类中属性值的方法
6.以方法作为形式的功能
有一些特殊功能的方法
【对象 Object】
对象是类的实例,可以认为它的使用就像任何变量一样
比如我们在使用Scanner类时,可以通过编写以下内容来创建该类的对象
Scanner sc= new Scanner(System.in);
创建完对应的对象之后,我们就可以使用它的功能了,现在我们的程序中有Scanner类的一个实例了
【创建一个Class的例子】
让我们开始看一个代表Car的java类的示例,我们的类,叫做car,将有以下属性:门的数量,车型和颜色,我们可能想要一个名为printCarDetails()的方法来打印出这些属性
于是我们得到了如下这个class
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()
{
//构造器,这种模式下它会给予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)
{
//在这种构造器中,使用者可以自定义Car的值
this.numberOfDoors = numberOfDoors;
this.colour = colour;
this.motorType = motorType;
lastCarReg++;
carReg = lastCarReg;
}
public Car(int doors)
{
numberOfDoors = doors;
colour = "Black";
motorType = 'I';
}
//Getter methods 下面是读取Car中各种属性的方法
//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 下面是设置/更改Car各种属性的方法
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;
}
*/
}
注意:在我们的class里面是没有main方法的,在main()方法(在另一个文件中)中,我们就可以像创建Scanner类的对象那样创建Car类的对象
比如:
public class TestCar{
public static void main(String args[]){
//Create a Car instance by calling the default constructor
//这里就是使用的默认值创建的Car,见前面Car类对应的部分
Car c1 = new Car();
//Create another Car instance by calling our general constructor with 3 parameters
//这里是使用了自定义的值来创建Car
Car c2 = new Car(5,"red",'E');
Car c3 = new Car(16);
//下面是各种方法的使用了,可以对照前文的Car类来看
//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());
}
}
【类和对象的命名约定】
1.创建类时,类名应始终以大写字母开头
2.创建类的对象时,对象名称应始终以小写字母开头,随后的任何单词都应以大写字母开头
【小结】
最关键的就是接受“类是模板”的这一思想,在这个模板中:
我们可以定义一类东西的属性,比如人Human有身高,体重,性别等等属性
我们可以对这些属性进行操作,也就是有方法,比如一个人减肥了,我们要更改他体重的属性值,我们就可以定义一个“更改体重”的方法来使用
我们可以把由这个模板产生的东西给予其它部分,比如我有一个驾驶车辆的方法CarDriver,它需要输入一个Human类型的参数作为驾驶员
那么我们就可以把Human产生的一个对象给予该方法
类的组成
【数组对象 Arrays of Objects】
接上篇例子,我们现在想要在我们的程序中创建多个Car
一个两个还好,要是我们想要创建多个car,一次次分别实例化就十分繁杂且混乱,于是有了数组对象
使用数组来存储相同类型的对象有助于简化操作
前文我们说过,可以把类当作一个存储数值的属性————就像我们用int、double等一样,所以数组对象的使用和之前数组的使用是一样的
再提一下,之前我们的int、double等等也是一种类,它们是Java中的默认类型的类,它们可以用数组储存
那么我们用户自定义的类也是“类”,由它实例的对象当然也能用数组储存咯
Car CarShouRoom [] = new Car [5]
for(int i = 0 ;i < 5 ; i++){
CarShouRoom [i] = new Car();
}
之前我们提到了类中的六个部分,下面我们来详细说说其中几个部分:
【构造函数 Constructors】
构造函数是一种特殊类型的方法,当将new关键字与对象一起使用时,将调用该方法
它们没有返回类型(甚至不是void),并且必须与类具有相同的名称
通常情况下,我们会拥有一个默认的构造函数(通常没有参数)以及至少一个具有1个或多个参数的其他构造函数
我们回顾一下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,我们之后再去细细讨论
this.numberOfDoors = numberOfDoors;
this.colour = colour;
this.motorType = motorType;
lastCarReg++;
carReg = lastCarReg;
}
【访问器和更改器方法 Accessor and Mutator Methods 】
访问器Accessor方法 用于返回(获取)属性值,它们也被称为getter方法
更改器Mutator方法用于更改(设置)属性值,它们也被称为setter方法
Accessor和Mutator方法为用户提供了一种,可以精确地与class中的数据交互的方法
其中访问器负责让使用者得到对应的数值,而更改器负责来设置和修改值
依旧以Car举例,下面这个方法就可以得到我们Car的颜色:
public String getColour() {
return colour;
}
注意,访问方法零输入参数,且具有返回类型。毕竟访问器就是用来获得对应数据的,肯定要有返回值的
由于该方法是public,任何类都可以调用它
下面看看一个更改器Mutator的例子,它会更改车的颜色:
public void setColour(String carColour) {
colour = carColour;
}
和Accessor相反,Mutator方法采用一个或多个参数,并且始终具有void返回类型。因为它的职责在于修改,需要接受修改值,但是不用返回值
二者实质上都是存在于Class里面的方法,通过它们的使用把二者分为了两个概念而已————实质上还是方法,没有什么特别的地方
Accessor和Mutator方法的命名约定:
公认的约定是方法名称的第一个单词的首字母是小写**(并且将是get或set),而所有其他单词的首字母是大写**
比如
对于Accessor:get<名字>(); 比如getCarReg()
对于Mutator :set<名字>(); 比如setMotorType()