package test;
class Cat{}
class WhiteCat extends Cat{}
class BlackCat extends Cat{}
public class Person {
public void feed(Cat cat){
System.out.println("feed cat");
}
public void feed(WhiteCat cat){
System.out.println("feed WhiteCat");
}
public void feed(BlackCat cat){
System.out.println("feed BlackCat");
}
public static void main(String[] args) {
Cat wc = new WhiteCat();
Cat bc = new BlackCat();
Person p = new Person();
p.feed(wc);
p.feed(bc);
}
}
why print
feed cat
feed cat
class Cat{}
class WhiteCat extends Cat{}
class BlackCat extends Cat{}
public class Person {
public void feed(Cat cat){
System.out.println("feed cat");
}
public void feed(WhiteCat cat){
System.out.println("feed WhiteCat");
}
public void feed(BlackCat cat){
System.out.println("feed BlackCat");
}
public static void main(String[] args) {
Cat wc = new WhiteCat();
Cat bc = new BlackCat();
Person p = new Person();
p.feed(wc);
p.feed(bc);
}
}
why print
feed cat
feed cat
System.out.println("feed cat");
}
有什么问题吗?
p.feed(wc);
p.feed(bc);
feed WhiteCat
feed BlackCat
package test;
class Cat{}
class WhiteCat extends Cat{}
class BlackCat extends Cat{}
public class Person {
public void feed(Cat cat){
System.out.println("feed cat");
}
public void feed(WhiteCat cat){
System.out.println("feed WhiteCat");
}
public void feed(BlackCat cat){
System.out.println("feed BlackCat");
}
public static void main(String[] args) {
WhiteCat wc = new WhiteCat();
BlackCat bc = new BlackCat();
Person p = new Person();
p.feed(wc);
p.feed(bc);
}
}
改成这样就行了,
public void eat(){
System.out.println("cat eat").
}
}
public class BlackCat extends Cat{
public void eat(){
System.out.println("black cat eat").
}
public static void main(String[] args){
Cat cat = new BlackCat().
cat.eat().
}
}这个时候的结果是:
black cat eat
为什么?????我想了解以下本质的区别呀?????
你有没有试过feed(null)会怎么样?
估计应该报错,编译错,因为它可以匹配了两个方法
改称feed((Cat)null),编译通过,跳用feed(Cat)方法
改称feed((BlackCat)null),编译通过,跳用feed(BlackCat)方法
改称feed((WhiteCat)null),编译通过,跳用feed(WhiteCat)方法
所以就直接调用它了。别的类型还要真正去做比较...这么理解就行,
理论有很多说道,很麻烦 :)good luck
public Test(Object o) {
System.out.println("1");
}
public Test(String a) {
System.out.println("2");
}
public static void main(String args[]) {
new Test("a");
}
}
楼上的你认为是调用哪个?
告诉你,返回结果是2,编译器只会找最接近的,这里跟多态无关
lz一开始写的代码,是关于方法调用参数传递的问题,这时候他会去找类型最匹配的去调用。
而lz后来写的那个代码,是多态的应用,对于方法的调用,去调用同名子类的方法。
而对于字段的调用,则还是调用基类的字段。
class Cat {
int i = 1;
public void eat() {
System.out.println("cat");
}
}class WhiteCat extends Cat {
int i = 2;
public void eat() {
System.out.println("WhiteCat");
}
}public class Test {
public void feed(Cat cat) {
System.out.println("feed cat");
} public void feed(WhiteCat cat) {
System.out.println("feed WhiteCat");
}
public static void main(String[] args) {
Test t = new Test();
Cat wc = new WhiteCat(); // 字段调用
System.out.println(wc.i); // i = 1
// 方法调用
wc.eat(); // WhiteCat
// 参数调用
t.feed(wc); // feed cat
}
}
public class Test { public Test(Object o) { System.out.println("1"); } public Test(String a) { System.out.println("2"); } public static void main(String args[]) { new Test("a"); } }
答案是2
但是如果改成new Test(null);
如果两个类型,比如这里Object 和String有继承关系,按照向上原则,先匹配子类
如果没有继承关系那就完了,比如楼主的String 和Integer,因为,这个函数可以匹配2个方法,且没有任何关系,就会产生编译错误(The constructor is ambiguous)构造函数有歧义 作为上面的补充
综上我总结一下。
分为3种情况:
第一种
方法在调用的时候,会去找最相近的类型,这个和多态没有关系
public class Test { public Test(Object o) {
System.out.println("1");
}
public Test(String a) {
System.out.println("2");
}
public static void main(String args[]) {
new Test("123");
}}答案是2
第二种
但是如果改成new Test(null);
public class Test { public Test(Object o) {
System.out.println("1");
}
public Test(String a) {
System.out.println("2");
}
public static void main(String args[]) {
new Test(null);
}}
如果两个类型,比如这里Object 和String有继承关系,按照向上原则,先匹配子类
第三种
如果没有继承关系那就完了,
比如
public class Test { public Test(Integer o) {
System.out.println("1");
}
public Test(String a) {
System.out.println("2");
}
public static void main(String args[]) {
new Test(null);
}}因为,这个函数可以匹配2个方法,且没有任何关系,就会产生编译错误(The constructor is ambiguous)构造函数有歧义好累,去睡了