今天在考虑实体类域代码复用时 重新关注了 组合(类内属性域引用其他类) 继承(is-a 向上转型(联系接口) 和对象概念抽象模型对应 ) 代理 (封装具体实现 可以仅代理一部分行为) 。
发现继承这里还是有很多坑的,总结一下。
public class Child{
private int id=8900;
protected int age;
public String name;
public Child(String name){
this.name = name;
}
//Child 私有方法 仅类内部可调用 对外部引用和子类不可见
private void childPrivate(){
System.out.println("childPrivate");
}
//对子类可见
protected void run(){
System.out.println("Child run");
}
protected void goToSchool(){
System.out.println("Child goToSchool");
}
//父类内重载
protected void say(){
System.out.println("Child say");
}
protected void say(String string) {
// TODO Auto-generated method stub
System.out.println("Child say"+string);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Child[] childArray = {new Girl("小玲"),new Boy("小明")};
for(Child child:childArray){
child.goToSchool();//多态
}
Girl girl = new Girl("小玲3");
girl.say();//继承方法
girl.say("haha");//覆写 串联覆写|完全覆写
girl.say(5);//类内重载 相对于父类是拓展
//Child girl = new Girl("小玲3");
// girl.say(5); 向上转型 接口变窄 但不会比Child的全部接口窄
}
}
public class Boy extends Child{
public Boy(String name) {
super(name);
// TODO Auto-generated constructor stub
}
//覆写
protected void goToSchool(){
System.out.println(name+"is a Boy,He will goToSchool");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
public class Girl extends Child{
public Girl(String name) {
super(name);
// TODO Auto-generated constructor stub
}
//拓展方法 父类没有 该类方法引用在向上转型后无法获取
public void cry(){
System.out.println("Girl cry");
}
//覆写
protected void goToSchool(){
System.out.println(name+"is a Girl ,She will goToSchool.");
}
//覆写
protected void say(String string) {
// TODO Auto-generated method stub
System.out.println(name+"is a Girl say "+string);
}
//拓展方法 父类没有 该类方法引用在向上转型后无法获取
//类内重载
protected void say(int id) {
// TODO Auto-generated method stub
System.out.println(name+"is a Girl say "+id);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
1 父类中 private 域仅父类内可见
Protected 和 public 域对子类可见 子类写相同方法是覆写,覆写(@override)调用super是串联父类实现的覆写
子类重载覆写的方法或者写自己的方法是拓展
子类没覆写父类方法 而调用父类方法是继承方法
如果拓展方法和父类private方法相同 依然属于拓展 因为相互不可见
子类都覆写了父类方法 各个子类向上转型的引用调用该方法依然可以找到正确子类实现,是动态后期绑定的结果,是多态
2 重载一般指同一个类内的方法动作。如果子类覆写了父类的重载方法,在用引用调用时可以视为 先继承未覆写方法,在重载。
3 子类拓展了方法 然后向上转型 接口变窄 将无法引用这些方法。但不会比Child的全部接口窄
4 向上转型后的引用本身指的是子类实例,可以强制向下转型(cast)
5 最好不要在子类中拓展的方法名字和父类中private 方法名一样
域和静态方法不具有多态,编译时绑定的,最好在不要再子类中有何父类相同的域变量名
6 继承结构 构造器中 最好不要调用覆写方法初始化 尽量用private方法初始化类
public class Girl extends Child{
public int I;
public Girl(String name) {
super(name);
I = 8;
}
protected void say(String string) {
// TODO Auto-generated method stub
System.out.println(name+"is a Girl say "+string+I);
}
}
public class Child{
public Child(String name){
this.name = name;
say(“世界你好!”);
}
protected void say(String string) {
// TODO Auto-generated method stub
System.out.println(name+”is a Child say “+string);
}
}
Girl girl = new Girl(“小玲3”);
小玲3 is a Girl say世界你好!0
产生这样的结果和继承结构初始化有关
先递归式的初始化父类再自己初始化 重复(类变量->对象变量->构造)过程
类变量 在类加载的准备阶段赋值默认值
常量 在类加载的准备阶段直接赋值
对象变量->构造 是在类加载 并分配了堆内存后进行的