目录
instance variables (attributes)
封装
数据类型
基本数据类型—小写 (只是数值)
引用数据类型—大写 (由地址信息代表)
class
在一个java文件中,class是最大的分类,是整体的“框架”。
而组成class这个“框架”的内容分为两部分:behavior and attributes
attributes就相当于是一个属性、特征,比如我的性别、身高等
behavior就相当于是一个动作,比如吃饭、睡觉等
eg. 其中的gender, height, and age就是attributes,而Human(), eatFood()和sleepHour()就是behavior
class Human{
public String gender;
public double height;
private int age;
public Human(){
/*code*/
}
public Human(String g, double h, int a){
/*code*/
}
public void eatFood(){
/*code*/
}
public int sleepHour(int t){
/*code*/
return t;
}
}
instance variables (attributes)
instance variables一般出现在整个class的最前面的部分,它存在的目的是事先定义好若干个变量方便后续方法的使用,并且让每一个新建的object都有自己不同的属性。
- public&private:
用public修饰的variables可以被随意调用,但是被private修饰后的variables只能在当前class文件中被使用。
instance methods (behaviors)
instance methods分为三种:constructor, accessor, and mutator.
- constructor
constructor就是header名字与class名一样的method,它没有return type(返回值)。存在目的为初始化(initialize)object。
并且在每一个class文件中,都会默认有一个空的constructor,被称为default constructor。比如上面例子里的public Human(){}就是一个default constructor。但是当自己创建了一个有参数列表的constructor后,default constructor会自己消失,所以这时候再需要用空的default constructor时就需要重新写一个了。
同时,也有有参数列表(parameter list)的constructor。比如上面例子中的Human(String g, double h, int a){}就是需要传参的constructor。其中,()内的参数为形式参数。对于需要传参的constructor,我们必须在client program中传入参数才可以正确地运行它。eg. (以下为client program)
public UseHuman{
public static void main(String args[]){
Human cici = new Human();
cici.Human("female", 168.0, 18);
}
}
用
object name.method name();
的形式就可以调用Human(String g, double h, int a){}了。
- accessor
accessor就是有return type的method,它会在运行后返回一些信息。特点:比如sleepHour(int t){},它除public外还有int在前面进行修饰(这个int为return type),并且在method body内还有“return”的出现,但是accessor不会修改object(对象)的任何一个东西。getter就属于是accessor的一种。
- mutator
mutator就是用于修改object内容的method, 比如setter就属于是mutator的一种。特征:有“void”
mutator和accessor的使用方法一样。
*setter and getter:
目的:对private成员变量进行修改和查看。
用法:
//setter:
public setAge(int a){
this.a = age;
}
//getter:
public int getAge(){
return a;
}
*overload重载
使用同一个方法名,但是使用不同的parameter list就是overload。通过overload,object可以以不同的方式被初始化(initialize)。
client class
由于没有程序入口的class是无法被运行的,就出现了client class专门用来运行程序。
在client class中,我们可以创建objects并运行在已经写好的class文件中的任何一种方法。
创建对象(object)
在创建一个对象的时候,应该用“new”关键字:
eg. Human cici = new Human(); 其中: 引用类型 object name 对象类型 ()内有无参数取决于constructor。
“this”的引用(reference)
- “this.”用于引用本class中的instance variables。eg. 其中的g, a, and h都是参数列表里的,“this.”用于将它们指代到instance variables中去
class Human{
String gender;
int age;
double height;
public Human(String g, int a, double h){
this.g = gender;
this.a = age;
this.h = height;
}
}
- “this()”用于引用本class中的constructors。()中参数的形式决定了用哪个constructor。
- 用“this.method name”添加在新的method中,就可以调用已经写好的method(不需要全打一遍了)。多overload一个constructor的原因是,当该文件被使用过后,再想要添加一个新的variable时是不能直接更改已经被用过的constructors的,必须overload一个新的,并加上新的参数。eg.相较于上面的例子多了一个name时:
class Human{
String gender;
int age;
double height;
String name;
public Human(){
/*code*/
}
public Human(String g, int a, double h){
this.g = gender;
this.a = age;
this.h = height;
}
public Human(String g, int a, double h, String n){
this.Human(String g, int a, double h);
this.n = name;
}
}
- null reference:当一个variable没有被初始化的时候,它就是个null reference。也可以通过“obj = null”的形式将该obj变成null reference。
null reference是不能调用任何一个method的,否则会出现“a NullPointerException”。
继承
"extends"
在创建一个class文件继承superclass(父类)的时候,需要用到“extends”这个关键词:eg.其中Worker为子类,Human为父类:
class Worker extends Human{
/*codes*/
}
要点:
- 子类会继承父类的所有属性,但子类的内容更丰富 -- 拥有自己特有的内容。
- 父类与子类之间只存在单一对应关系,但是一个父类可以有很多个子类(但一个子类不能同时继承很多个父类)。
- 子类可以调用父类中的东西,但是父类不能调用子类的东西。
"super()"
目的:调用父类中的constructor
方法:
- super(); 调用父类中的default constructor
- super.XXX; 用来调用父类中的method或属性
class Worker extends Human{
String position;
double workTime;
public Worker(){
super();
}
//假设Human类中有doWork这个method
public doWork{
super.doWork();
/*more codes*/
super.age = 18;
}
}
override
在子类中复写&定义一个方法,让它和父类中heading相同的方法内容(method body)不同。且在程序运行过程中,java程序会自己选择合适的method使用。
object class
toString() : 被print之后会出现对象的类名和存储地址(16进制)
equals() : 用于判断内容地址是否相同(即是否用的同一块的内存 ) -- (equals为boolean类型体系中的一个,即返回值为true / false)
Upcasting & Downcasting
- upcasting向上转型 - 子类向父类转型
由于新建对象时,对象的类型由引用类型和对象类型同时决定,更改新建对象的引用类型为父类就可以实现向上转型。
//原新建对象时:
Student Cici = new Student;
//向上转型后:
Human Cici = new Student;
目的:增加实际情况中对象的灵活性。- 因为在向上转型后,新建的对象就可以在不添加引用类型的情况下新建任何一个子类的对象。
比如:
//当Human底下有Student, Worker, 和Manager时,就可以:
Human Cici = new Student;
Cici = new Worker;
Cici = new Manager;
- downcasting向下转型 - 父类向子类转型
由于对象的类型由引用类型和对象类型同时决定,在调用子类的方法时,就不能“跨级”使用。若需要“跨级”使用,那么就要进行如强制类型转换般的操作。
eg. (*其中目的为调用Student里面的getGrade()的方法)
Human a = new Student();
int x = a.getGrade();
//但Human里面没有getGrade()这个method而只有Student里面有,所以就要改成:
int x = ((Student)a).getGrade();
Abstract class
- 如果一个类中含有抽象方法,该类必须声明为抽象类
- 抽象方法只有method head,没有method body
- 抽象类只能被继承,无法生成object (被实例化)= 只有被继承之后才能发挥作用,其子类也用"extends"来继承
- 抽象类也有constructor,但不是用来生成对象的,而是用来被子类的constructor调用的
- 继承了抽象类的子类,如果不是抽象类,就要复写(override)抽象方法(method)
- 抽象类的subclass必须写method body,不然在运行时就会出错
- 抽象类中既有abstract的,也可以有具体的method(有body的method)
//有abstract method,就要被声明为抽象类
abstract class Exam{
String examName;
public Exam(String e){
this.e = examName;
}
public abstract int doAddition(); // 没有方法体的method
//无法生成一个对象
}
class Math extends Exam{
int marks;
String grades;
public Math(String e, int m){
super.(e);
this.m1 = marks;
this.m2 = marks;
}
public int doAddition(){ //必须override原来Exam类里的才行
a = m1 + m2;
return a;
}
}
Interface class
"implements"
interface class在被“使用”的时候需要用"implements"来连接,并且一个类可以同时“使用”很多个interface class,比如:
class Human implements Player,Teacher{
/*codes*/
}
与abstract class不同的是,在interface class中,只有抽象方法。所以在使用interface class的时候,必须要override其中所有的方法。
但同时,在interface class中也是不能新建对象(被实例化)的。
多态
- 角度一:对象可以有很多种行为,但具体执行哪个method,不仅由引用类型决定,还由对象类型来决定。
- 角度二:具体执行的method是哪一个,不是由引用类型来决定的,是由子类中override的method来决定的(看哪个合适就会在compile time自主运行哪个)。