static关键字
static的真正作用是用于区分成员变量、方法、内部类、初始化模块这四种成员到底属于类本身还是属于实例。在类中定义的成员,static相当于一个标志,有static修饰的成员属于类本身,没有static修饰的成员属于该类的实例。
静态成员不能直接访问非静态成员。
访问控制符
private < default < protected < public
private | default | protected | public | |
---|---|---|---|---|
同一个类中 | ✓ | ✓ | ✓ | ✓ |
同一个包中 | ✓ | ✓ | ✓ | |
子类中 | ✓ | ✓ | ||
全局范围内 | ✓ |
如果使用protected来修饰一个方法,通常是希望其子类来重写这个方法。
外部类只能用public和默认来修饰。
如果java类的每个实例变量都被private修饰,应该为每个实例变量提供setter和getter方法,这个类就符合JavaBean规范,是个封装良好的类。
使用访问控制符的几条基本原则:
1.类里的绝大多数成员变量都应该使用private修饰,只有一些static修饰的、类似全局变量的成员变量,才可能考虑用public修饰。除此之外,有些方法只用于辅助实现该类的其他方法,这些方法被称为工具方法,也应该使用private修饰。
2.某个类主要做其他类的父类,该类的大部分方法希望被子类重写,不想被外界直接调用,用protected修饰。
3.希望暴露给其他类自由调用的方法应该使用public修饰。例如,类的构造器,外部类等。
super关键字
super用于限定该对象调用它从父类继承得到的实例变量或方法。和this关键字一样,不能出现在static修饰的方法中。
引用变量的强制类型转化
在进行强制类型转换前,先用instanceof运算符判断是否可以成功转换,从而避免ClassCastException异常,保证程序的健壮性。
把子类对象赋给父类引用变量时,被称为向上转型(upcasting),这种转型总是可以成功。
把父类对象赋给子类引用变量时,需要进行强制转换,使用instanceof运算符可让强制转换类型更安全。
if(objPri instancdof String)
{
String str = (String)objPri;
}
instanceof 的用法
instanceof运算符的前一个操作数通常是一个引用类型变量,后一个操作数通常是一个类(也可以是接口,可以把接口理解成特殊的类),它用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。
instanceof运算符前面操作数的编译时类型要么与后面的类相同,要么与后面的类有父子继承关系,否则回引起编译错误。
instanceof和(type)是java提供的两个相关的运算符。
继承的使用
继承是实现复用的手段,但破坏了程序的封装性。
如果想把某些类作为最终类,即不能当成父类,则可以使用final修饰这个类,例如JDK提供的java.lang.String类和java.lang.System类。
此外,使用private修饰这个类的所有构造器,保证子类无法调用该类的构造器,也就无法继承此类。
对于把所有的构造器都使用private修饰的父类而言,可提供一种静态方法,用于创建该类的实例。
何时需要从父类派生出新的子类:
1.子类需要增加额外属性,而不仅仅是属性值的改变
2.子类需要增加自己独有的行为方式(包括增加新的方法和重写父类方法)。
利用组合实现复用
class Animal
{
private void beat()
{
System.out.println("心脏跳动...");
}
public void breath()
{
beat();
System.out.println("吸一口气,吐一口气,呼吸中。。。");
}
}
class Bird
{
//将原来的父类组合到原来的子类,作为子类的一个组合成分
private Animal a;
public Bird(Animal a)
{
this.a = a;
}
//重新定义一个breath()方法
public void breath()
{
//直接复用Animal提供的breath()方法来实现Bird中的breath()方法
a.breath();
}
public void fly()
{
System.out.println("我在天空自由的飞翔。。。");
}
}
class Wolf
{
private Animal a;
public Wolf(Animal a)
{
this.a = a;
}
public void breath()
{
a.breath();
}
public run()
{
System.out.println("I am running...");
}
}
public class CompositeTest
{
public static void main(Stringp[] args)
{
//此时需要显式的创建被组合的对象
Animal a1 = new Animal();
Bird b = new Bird(a1);
b.breath();
b.fly();
Animal a2 = new Animal();
Wolf w = new Wolf(a2);
w.breath();
w.run();
}
}
继承表达的是一种(is a)的关系,组合表达的是一种(has a)的关系
初始化块–Java类里的第四种成员
当java创建一个对象时,系统优先为该对象的所有实例变量分配内存(前提是该类已经被加载过了),接着程序开始对实例变量进行初始化,先执行初始化块或者声明实例变量时指定的初始值(执行顺序与他们在源代码中的排列顺序一致),再执行构造器里指定的初始值。
静态初始化
定义初始化块时使用static修饰符,也被称为类初始化(普通初始化块负责对对象进行初始化,类初始化负责对类进行初始化)。
比普通初始化块先执行。
属于类的静态成员,不能访问非静态成员,包括不能访问实例变量和实例方法。
Java系统加载并初始化某个类时,总是保证该类的所有父类(包括直接父类和间接父类)全部加载并初始化。