class Chicken{
public void live(){
System.out.println("這是一隻雞");
}
}
class BaiqieChicken extends Chicken{ }
但僅是定義一個白切雞類是不夠的,因為在此我們只能做到復用父類的屬性和行為,而沒有呈現出行為上的不同的形式或形態。2. 必須有重寫重寫,簡單地理解就是重新定義的父類方法,使得父類和子類對同一行為的表現形式各不相同。我們用白切雞類來舉個慄子。class BaiqieChicken extends Chicken{
public void live(){
System.out.println("這是一隻會被做成白切雞的雞");
}
}
Chicken c = new BaiqieChicken();
c.live();
BaiqieChicken bc = new Chicken();
bc.live();
class Chicken{
public void live(String lastword){
System.out.println(lastword);
}
}
class BaiqieChicken extends Chicken{
public void live(String lastword){
System.out.println("這隻白切雞說:");
System.out.println(lastword);
}
}
class BaiqieChicken extends Chicken{
public void live(){
System.out.println("這是一隻會被做成白切雞的雞");
}
public void live(String lastword){
System.out.println("這隻白切雞說:");
System.out.println(lastword);
}
}
interface Chicken{
public void live();
}
class BaiqieChicken implements Chicken{
public void live(){
System.out.println("這是一隻會被做成白切雞的雞");
}
}
class ShousiChicken implements Chicken{
public void live(){
System.out.println("這是一隻會被做成手撕雞的雞");
}
}
public class StaticDispatch {
static abstract class Human{ }
static class Man extends Human{}
static class Woman extends Human{}
public void sayHello(Human guy){
System.out.println("hello, guy!");
}
public void sayHello(Man guy){
System.out.println("hello, gentleman!");
}
public void sayHello(Woman guy){
System.out.println("hello, lady!");
}
public static void main(String[] args){
Human man = new Man();
Human woman = new Woman();
StaticDispatch sr = new StaticDispatch();
sr.sayHello(man);
sr.sayHello(woman);
}
}
javac -verbose StaticDispatch.class
public class StaticDispatch {
static abstract class Human{
protected abstract void sayHello();
}
static class Man extends Human{
@Override
protected void sayHello() {
System.out.println("man say hello");
}
}
static class Woman extends Human{
@Override
protected void sayHello() {
System.out.println("woman say hello");
}
}
public static void main(String[] args){
Human man = new Man();
Human woman = new Woman();
man.sayHello();
woman.sayHello();
}
}
man say hello
woman say hello
找到操作數棧頂的第一個元素所指向的對象的實際類型,記作C。
如果在在類型C中找到與常量中的描述符和簡單名稱都相符的方法,則進行訪問權限校驗,如果通過則返回這個方法的直接引用,查找過程結束;如果不通過,則返回java.lang.IllegalAccessError異常。
否則,按照繼承關係從下往上依次對C的各個父類進行第2步的搜索和驗證過程。
如果始終沒有找到合適的方法,則拋出java.lang.AbstractMethodError異常。
我們可以看到,由於invokevirtual指令在執行的第一步就是在運行期確定接收者的實際類型,所以字節碼中會出現invokevirtual指令把常量池中的類方法符號引用解析到了不同的直接引用上,這個就是Java重寫的本質。總結一下,重載的本質是在編譯期就會根據參數的靜態類型來決定重載方法的版本,而重寫的本質在運行期確定接收者的實際類型。繼承假如我們有兩個類:生物類、貓類。
生物類:
class Animal{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
class Cat{
private String name;
private String sound;
public void setName(String name){
this.name = name;
}
public void setSound(String sound){
this.sound = sound;
}
public String getName(){
return this.name;
}
public String getSound(){
return this.sound;
}
}
class Animal{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
class Cat extends Animal{}
public class Test{
public static void main(String[] args){
Cat cat = new Cat();
cat.setName("貓");
System.out.println(cat.getName());
}
}
class Animal{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
class Cat extends Animal{
private String sound;
public void setSound(String sound){
this.sound = sound;
}
public String getSound(){
return this.sound;
}
}
public class Test{
public static void main(String[] args){
Cat cat = new Cat();
cat.setName("NYfor2020")
cat.setSound("我不是你最愛的小甜甜了嗎?");
System.out.println(cat.getName()+":"+cat.getSound());
}
}
class ACat{
public void mewo(){...}
}
class BCat{
public void mewo(){...}
}
class CCat extends ACat, BCat{
@Override
public void mewo(){...?} //提問:這裡的mewo()是繼承自哪個類?
}
class ACat{}
class BCat extends ACat{}
class CCat extends BCat{}
class ACat {
private String sound = "meow";
public String getSound() {
return sound;
}
public void setSound(String sound) {
this.sound = sound;
}
}
class BCat extends ACat {
}
public class Test {
public static void main(String[] args) {
BCat b = new BCat();
b.setSound("我不是你最愛的小甜甜了嗎?");
System.out.println(b.getSound());
}
}
class ACat {
final String sound = "你是我最愛的小甜甜";
public String getSound() {
return sound;
}
public void setSound(String sound){
this.sound = sound; //這句執行不了,會報錯的
}
}
class BCat extends ACat {
}
class A {
public A(){
System.out.println("我不是你最愛的小甜甜了嗎?");
}
public A(String q){
System.out.println(q);
}
}
class B extends A {
public B(){
System.out.println("你是個好姑娘");
}
}
public class Test {
public static void main(String[] args) {
B b = new B();
}
}
class A {
public A(String q){
System.out.println(q);
}
}
class B extends A {
public B(){
super("我是你的小甜甜?");
System.out.println("你是個好姑娘");
}
}
public class Test {
public static void main(String[] args) {
B b = new B();
}
}