类的继承:http://t.csdn.cn/vhf6p
多态,封装,包,static,初始化块:http://t.csdn.cn/g56SQ
继承与组合
代码复用的两种手段。
继承的缺点:父类的细节对子类不再透明,破坏父类封装性。
应当
- 尽量将父类成员变量用private修饰
- 父类中的辅助方法应用private修饰
- 不希望被子类重写的方法用final修饰
- 希望被重写,但不希望被外部访问,用protected修饰
- 尽量不要在父类构造器中调用将被覆写的方法
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
Sub sub=new Sub();//null
}
}
class Base{
private int date;
public int getDate(){
return date;
}
public void setDate(int x){
date=x;
}
public void test(){
System.out.println("将被覆写");
}
public Base(){
test();
}
}
class Sub extends Base{
private String mine;
public void test(){
System.out.println(mine);
}
}
不想被继承除了可以用final修饰,还可以将父类构造器用private修饰,提供一个static方法创建实例。(感觉没什么用)
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
SuperClass sup=SuperClass.Constructor(6);//
System.out.println(sup.getDate());//6
}
}
class SuperClass{
private int date;
private SuperClass(int x){
date=x;
}
public static SuperClass Constructor(int x){
return new SuperClass(x);
}
public int getDate(){
return date;
}
public void setDate(int x){
date=x;
}
}
class SubClass extends SuperClass{
}//无法继承,找不到构造器
组合
继承实现代码复用
public class Main {
public static void main(String[] args) {
Cat A=new Cat();
Dog B=new Dog();
A.Call();
A.eat();
B.Call();
B.eat();
}
}
class Animal{
public void eat(){
System.out.println("eating");
}
}
class Cat extends Animal{
public void Call()
{
System.out.println("喵喵喵");
}
}
class Dog extends Animal{
public void Call()
{
System.out.println("汪汪汪");
}
}
组合实现代码复用
public class Main {
public static void main(String[] args) {
Cat A=new Cat();
Dog B=new Dog();
A.Call();
A.eat();
B.Call();
B.eat();
}
}
class Animal{
public void eat(){
System.out.println("eating");
}
}
class Cat{
Animal t=new Animal();
public void Call()
{
System.out.println("喵喵喵");
}
public void eat(){
t.eat();
}
}
class Dog{
Animal t=new Animal();
public void Call()
{
System.out.println("汪汪汪");
}
public void eat(){
t.eat();
}
}
分析:
从代码复用的角度,二者效果一致
在继承中,子类是父类的扩展。那么在组合里面,同样可以让旧类做为新类的一部分,到达扩展目的。
从封装性的角度,
在继承中,为了保证父类的良好封装性,在设计父类时,限制较多。但是,组合中,一个封装良好的旧类就不用顾虑会暴露给新类。
从逻辑的角度,
如果两个类符合is的关系,就可以用继承体现;如果符合has的关系,就可以用组合体现。