java基础知识(二)-----多态和构造函数

  一:前言

   最近由于面试了新浪公司,面试官问我的问题我都不知道,觉得自己好菜,所以最近决定再把java基础给搞一遍,真的觉得自己好菜。每天看一点,那个家伙说《java编程思想》最少要看三遍,我一遍都没看完。现在每次都写写自己的最新指导的知识点吧。努力!!!刚刚在一个群上说了下这,别人给我说了句话“你要提醒自己,所有的技术别人能学会的你迟早能学会,没什么大不了的”。记住

  二:内容

  (1):关于构造方法的问题

    我们每次写一个类中,都会说在类中加一个无参数的构造方法,我时常在想,这个无参数的构造函数有什么用,我一直很困惑,但是现在我可能明白了一点吧,由于那次看了下ArrayList的源码我才明白点,先上了ArrayList代码看看

  

 /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param   initialCapacity   the initial capacity of the list
     * @exception IllegalArgumentException if the specified initial capacity
     *            is negative
     */
    public ArrayList(int initialCapacity) {
    super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
    this.elementData = new Object[initialCapacity];
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
    this(10);
    }

我自己也写了个测试了下如下:

 1 package thinker;
 2 public class ConstrutsDemo01 {
 3     public String a;
 4     public void find(){
 5         System.out.println("我的测试端");
 6     } 
 7     
 8     public ConstrutsDemo01(){
 9         this("5");
10     }
11     
12     public ConstrutsDemo01(String a){
13         this.a=a;
14     }
15     
16     public static void main(String args[]){
17         ConstrutsDemo01 c=new ConstrutsDemo01();
18         ConstrutsDemo01 c2=new ConstrutsDemo01("1");
19         System.out.println("无参数构造方法"+c.a);
20         System.out.println("有参数的构造方法"+c2.a);
21     }
22 }

这里给我的答案是,通过构造方使得我们既可以在实例化时传递参数,也可以不传递参数。好处显而易见吧。不知道这是不是需要构造函数的好处了!

 

(二):多态机制的缺陷

 

 

B:对于私有的方法无法覆盖,如下代码

 1 package thinker;
 2 
 3 public class Animal {
 4     private void fun(){
 5         System.out.println("我是动物的总称");
 6     }
 7     public static void main(String[] args) {
 8         Animal a=new Dog();
 9         a.fun();//结果是“我是动物的总称”
10     }
11 }
12 
13 
14 package thinker;
15 
16 public class Dog extends Animal {
17     public void fun(){
18         System.out.println("动物:狗狗");
19     }
20     
21 }

所以我们得到的结论是“对于私有的方法我们没办法进行覆盖操作”

B:多态的域域静态方法

  其实我也一样,刚刚了解多态的时候我也觉得,比如子类和父类中都有的相同变量那么如果调用这个变量,是否是和方法一样,调用得是子类的这个变量值了。显而我错了,只有普通的方法调用可以是多态的。如果你直接访问某个域,这个访问域就将在编译期进行解析如下:

package thinker;

public class Animal {
    public String name="动物";
    public void fun(String name){
        System.out.println("我是动物的总称"+name);
    }
    
}
package thinker;

public class Dog extends Animal {
    public String name="猫";
    public void fun(String name){
        System.out.println("动物:"+name);
    }
    
    public String getName(){
        return super.name;
    }
    
    public static void main(String[] args) {
        Animal a=new Dog();
        Dog d=new Dog();
        System.out.println(a.name);//打印结果“动物”
        System.out.println("父类的name:"+d.getName()+"--子类的:"+d.name);//打印结果“父类的name:动物--子类的:猫”
    }
}

在《java编程思想》中是这样写的:“当Dog对象转型为Animal引用时,任何域访问操作都将由编译器解析,因此不是多态的”

在说有关静态的方法:如果某个方法是静态的,它的行为就不具有多态性:

package thinker;

public class Animal {
    public String name="动物";
    public static void fun(String name){
        System.out.println("我是动物的总称:"+name);
    }
    public void fprint(){
        System.out.println("父类:非静态的类");
    }
    
}
package thinker;

public class Dog extends Animal {
    public String name="猫";
    public static void fun(String name){
        System.out.println("动物:"+name);
    }
    public void fprint(){
        System.out.println("子类:非静态的类");
    }
    public static void main(String[] args) {
        Animal a=new Dog();
        a.fun("mouse");//结果“我是动物的总称mouse”
        a.fprint();//结果“子类:非静态的类”
    }
}

由此可以看出我们的fun()是静态的,调用打印的结果也是父类的方法,而fprint()方法是非静态的,调用打印结果是子类方法。可得:

如果某个方法是静态的,则它的行为就不具有多态性

 

 

三:有关实例化顺序

package org.duotai;

public class Computer {
    private int i=1;
    
    public void find(){
        System.out.println("Computer find()");
    }

    public Computer() {
        System.out.println("Computer find() be");
        System.out.println("构造方法"+i);
        find();//这里调用得其实是子类的方法,然而此时子类的数据(即i)还未实例化,所以在打印出的数据位0
        System.out.println("Computer find() af");
    }
    
    
}




package org.duotai;
public class CPU  extends Computer{
    private int i=5;
    
    public CPU(int i){
        this.i=i;
        System.out.println("构造方法CPU.i="+i);
    }
    
    public void find(){
        System.out.println("方法CPU.i="+i);//由于此时未实例化所以值为0
    }
}



package org.duotai;
public class DTDemo01 {
    public static void main(String args[]){
        new CPU(2);//调用
    }
}

在这里我们打印出的结果是:

Computer find() be
构造方法1
方法CPU.i=0
Computer find() af
构造方法CPU.i=2

可以看到“方法CPU.i=0”,所以我们得到,在父类实例化时调用方法,由于子类中的数据还未实例化,造成此种情况。

实例化顺序:自己断点运行了下,发现在父类构造时还是先去初始化定义的变量,再来执行的构造方法内的内容。

 

 *******************************************

姓名:耗子

名言:机会都是留给有准备的人,GO!

******************************************

posted @ 2014-11-04 16:40  郁闷的耗子  阅读(422)  评论(0编辑  收藏  举报