这是 UML (统一建模语言,Unified Modeling Language) 的类别图,常用来描述类别之间的关系。 实心箭头表示继承关系,由子类别指向父类别。 图中读作 Dog 继承 Animal 。另外一种常见的说法是: Dog is a Animal. 继承的概念用 is a 来表述。反过来说 Animal is a Dog.是不成立的,利用 is a 可以帮助思考。
我们要建构的是 C ,而 C 是 B 的延伸,所以要先有 B ,而 B 是 A 的延伸,所以要先有 A ,而 A 是 Object 的延伸,所以要先有 Object ,于是就从最顶端的父类别一直建构下来。 好,现在我知道需要从父类别初始化下来,但构造呢?一个类别可以定义无数个构造,他怎么知道我要用哪个构造方法来构造我的对象?到底是以什么机制来构造父类的? 嗯,回想一下,当初在定义类的时候,如果没有定义任何构造方法,Java会帮你定义一个不带参数不做任何事的构造方法,现在同样的老招又来一次! 只要你的构造方法中 没有调用其他构造方法 ,就会在 第一行 偷偷帮你加上去一个 super(); 有多偷偷呢?你连看都看不到! !但他就是存在于最后的程序代码中。
classA{ voidprintInfo(){ System.out.println("hello, I am A."); } } classBextendsA{ voidprintInfo(){ System.out.println("hello, I am B."); } } classCextendsA{ }
上述程式中, B 与 C 都是继承 A ,表示拥有了 A 所有的成员,但 B 重写了 printInfo() 方法,而 C 没有。所以在调用的时候, 对象B 会使用 B 类别重写的方法,而 对象C 因为 C 类没有自己定义重写,所以会使用到父类 A 所定义的 printInfo() 。 好,那来谈谈 重写 的 限制 。
classA{ // (↓关键字 final) publicfinalvoidprintInfo(){ System.out.println("hello, this is A."); } } classBextendsA{ // 编译错误 ↓ 利用final修飾的方法不能被重写。 publicvoidprintInfo(){ System.out.println("hello, this is B;"); } }
在 A类 的 printInfo() 方法利用 关键字 final 修饰,所以任何继承他的子类别都不能重写这个方法,否则会产生编译错误: Cannot override the final method from A . 第二点,方法名称、回传型态、参数个数必须相同。 嗯,如果不一样的话,就是自己再定义一个新方法了阿! !跟重写有什么关系 XD
1 2 3 4 5 6 7 8 9 10
classA{ publicvoidprintInfo(){ System.out.println("hello, this is A."); } } classBextendsA{ publicvoidprintInfo2(){ System.out.println("hello Tina, nice to meet you <3"); } }
恩,就是多定义一个方法,没什么好说的,这根本不是重写。
第三点,子类方法修饰符权限不能小于父类方法。 简单来说,如果父类说这个方法是对 全世界公开(public) 的方法,你要重写就不能 占为己有(private) 。 tips: 存取修饰符的开放权限从大到小: public -> protected -> (no modifier) -> private 如果父类说此方法是 protected ,那子类重写时的修饰符必须是 public 或 protected 。 如果父类说此方法是 private ,那子类重写时的修饰符必须是 public 或 protected 或 (no modifier) 或 private 。 关键是权限的开放范围不得小于重写对象。
1 2 3 4 5 6 7 8 9 10 11 12
classA{ // 注意修饰符是(no modifier) voidprintInfo(){ System.out.println("hello, this is A."); } } classBextendsA{ // ↓ 编译错误,子类重写方法修饰符权限小于父类方法 privatevoidprintInfo(){ System.out.println("hello, this is B."); } }
在 A类 中的 printInfo() 方法修饰子是 (no modifier) ,依据重写的开放权限规则, B类 继承了 A类 想重写 printInfo() ,重写的开放权限必须为 public 或 protected 或 ( no modifier) ,重点就是不能小于重写对象,否则会发生编译错误: Cannot reduce the visibility of the inherited method from A .