Learn Java for Android Development Second Edition 笔记(二)

来源:互联网 发布:linux exec函数族 编辑:程序博客网 时间:2024/04/18 20:55

类和对象(Class and Objects)

声明对象

class Image{// various memberdeclarations}Image image = newImage();

Image类并没有显示的去声明构造函数,Java会自动创建一个缺省的无参构造函数。但是如果只要声明了一个构造函数,Java就不会自动去创建无参构造函数。

一个构造函数可以依赖于另外一个构造函数,通过this指针来实现。

构造函数没有返回值。

Image(){System.out.println("Image()called");}Image(Stringfilename){this(filename, null);System.out.println("Image(Stringfilename) called");}

局部变量不能和函数输入参数同名,因为两者作用域重叠。

类成员变量可以和函数输入参数同名,类成员变量可以通过this.field来与函数输入参数区分,如下例子:

String make;String model;int numDoors;Car(String make,String model){this(make, model, 4);}Car(String make,String model, int nDoors){this.make = make;this.model = model;numDoors = nDoors;}

当一个对象被创建时,未被显示初始化的变量会被赋值为0.

静态成员变量在所有对象实例里只有唯一一份拷贝,依赖于类而不是对象,所以被称为class fields,而一般的成员变量称为instance fields。静态成员变量通过类名而不是对象名来访问。

声明只读成员变量

当想声明一个成员变量为只读的,可以加final关键字。

final变量有两种类型,根据变量初始化的地方不一样而不同。当在构造函数里初始化时,这种变量称为blank final,因为它只有在构造函数被调用了才有一个真正的值。

如果想要一个真正的常量,并且对所有对象的都一致,则需要创建class field,并加上static,如下例子:

class Employee{final static intRETIREMENT_AGE = 65;}

类方法

当需要能将对象的几个方法级联使用时,需要用到this指针,如下例子:

public classSavingsAccount{int balance;SavingsAccountdeposit(int amount){balance += amount;return this;}SavingsAccountprintBalance(){System.out.println(balance);return this;}public static voidmain(String[] args){newSavingsAccount().deposit(1000).printBalance();}}

当想不创建一个对象而给外界提供一个方法时,通过创建static的成员函数来实现,这种成员函数称为class methods。class method不能访问instance field和instance method,只能访问class field和class method

Java传递参数给函数都是传值(pass by value),对于原子类型,是传递一个副本,对于对象类型,是传递引用本身。例如:

Employee emp = newEmployee("John ");intrecommendedAnnualSalaryIncrease = 1000;printReport(emp,recommendAnnualSalaryIncrease);printReport(newEmployee("Cuifen"), 1500);

因此在printReport函数里,不能把别的Employee引用赋值给emp

声明变参类型的函数为如下方法:

double sum(double. .. values){int total = 0;for (int i = 0; i< values.length; i++)total += values[i];return total;}

Overload方法

函数名称相同,但是输入参数不同的方法,称为方法重载。不能仅有返回值类型不同的重载方法。

设计一个类时,目标是提供一个有用的接口给调用者使用,而屏蔽具体接口的实现。尽量不要让调用者直接访问对象的成员变量,这样可以仅改变对象成员函数的实现,而不需修改调用者的代码。

Java提供四种级别的访问控制:


 声明为public的类必须被保存在同样命名的文件当中。

一个源代码文件里,最顶层的class仅能有一个声明为public。

Java也提供了一种方法可以访问另一个对象的private变量或方法:必须在这个类自身的上下文里才能直接访问同样类对象的private变量,如下例子:

public class PrivateAccess{private int x;PrivateAccess(int x){this.x = x;}boolean equalTo(PrivateAccess pa){return pa.x == x;}public static void main(String[] args){PrivateAccess pa1 = new PrivateAccess(10);PrivateAccess pa2 = new PrivateAccess(20);PrivateAccess pa3 = new PrivateAccess(10);System.out.println("pa1 equal to pa2: " + pa1.equalTo(pa2));System.out.println("pa2 equal to pa3: " + pa2.equalTo(pa3));System.out.println("pa1 equal to pa3: " + pa1.equalTo(pa3));System.out.println(pa2.x);}}

类和对象的初始化

类和对象的成员变量的初始化方法有以下几种:

1:声明但不赋值,系统会自动初始化为0

2:声明且赋值

3:在构造函数里赋值

4:class initializers,在这个类导入系统时赋值

5:instance initializers,在这个对象创建时赋值

  • class initializers是在类里以static开始并用{}包含起来的一段代码。会存在类的<clinit>()方法里,参考一下例子:

class C{static{System.out.println("class initializer 1");}static int counter = 1;static{System.out.println("class initializer 2");System.out.println("counter = " + counter);}}
以上class initializer和class field initializer依序执行。

  • instance initializers
不是所有的类都有构造函数,Java提供了一种以{}包围的代码段来实现instance变量初始化,如以下例子:

class Graphics{double[] sines;double[] cosines;{sines = new double[360];cosines = new double[sines.length];for (int degree = 0; degree < sines.length; degree++){sines[degree] = Math.sin(Math.toRadians(degree));cosines[degree] = Math.cos(Math.toRadians(degree));}}}

如果类没有构造函数,Java会创建一个缺省的<init>()方法来存储对象变量的初始化代码,如果有构造函数,则为每一个构造函数创建对应的<init>()方法。

instance initializers一般很少使用。

以上各种初始化方法的顺序为:

  • class field在类被导入后,值会被初始化为0或用户设定值。
  • class initializers在<clinit>()返回前执行完。
  • 接下来是intance field和instance initializer执行。
  • 最后是构造函数执行。

在Android平台下实测下来,instance initializer和构造函数的执行顺序不固定,有可能是多线程执行了?


 




0 0
原创粉丝点击