首页 > 代码库 > java面向对象学习笔记(2)

java面向对象学习笔记(2)

一.构造器

   1.构造器最大的用处就是在创建对象时执行初始化,每个java类必须包含一个或一个以上的构造器。一般系统会提供一个无参的构造器,但是如果我们自己定义了一个构造器后它就不会再起作用了。如果我们为一个类编写了有参构造器,那么最好还是为该类提供一个无参的构造器。

   2.构造器的重载

      同一个类中可以包含有多个构造器,多个构造器的形参列表不同,即被称为构造器的重载。系统通过new调用构造器时,系统将根据传入的实参列表来决定调用哪个构造器。示例代码如下:


<span style="font-size:18px;">package test;

public class ConstructorOverload {

	public String name;
	public int count;
	//提供无参构造器
	public ConstructorOverload(){
		
	}
	//提供带两个参数的构造器
	public ConstructorOverload(String name,int count){
		
		this.name=name;
		this.count=count;
	}
	public static void main(String[] args){
		
		//通过无参构造器创建ConstructorOverload对象
		ConstructorOverload oc1 = new ConstructorOverload();
		//通过有参构造器创建ConstructorOverload对象
		ConstructorOverload oc2 = new ConstructorOverload("longkaili",21);
		System.out.println(oc1.name+" "+oc1.count);
		System.out.println(oc2.name+" "+oc2.count);
	}
}
</span>
如果一个构造器中完全包含另一个构造器的执行体,那么可以通过this关键字进行调用,这样可以增加代码的可维护性。示例代码如下:


<span style="font-size:18px;">package test;

public class Apple {

	public String name;
	public String color;
	public double weight;
	public Apple(){
		
	}
	public Apple(String name,String color){
		
		System.out.println("别的构造器调用了我(0.0)");
		this.name=name;
		this.color=color;
	}
	public Apple(String name,String color,double weight){
		
		//通过this调用另一个构造器的初始化代码。
		this(name,color);
		this.weight=weight;
	}
	public static void main(String[] args){
		Apple ap = new Apple("longnkaili","red",110);
		System.out.println(ap.name+" "+ap.color+" "+ap.weight);
	}
}
</span>


二.java中的继承

   java的继承和C++最大的不同就是:java是单继承,每个子类只能有一个直接的父类(当然间接的父类就随便了)。

java的继承通过关键字extends实现;子类继承父类后可以获得父类的所有方法和File,但是不能获得父类的构造器。

下面从几个方向说明继承需要注意的地方。

   1.重写父类的方法

       如果父类的某个方法对子类是可见的(不为private),然后又在子类中定义了一个与其完全一样的方法,则称为方法的重写,也称为方法覆盖。方法的重写要遵从“两同两小一大”的原则。需要注意的是,覆盖方法和被覆盖方法必须要么都是类方法要么都是实例方法,不能一个是类方法,一个是实例方法。下面是一份示例代码:


package test;

public class Bird {

	public void fly(){
		System.out.println("我在天空自由自在的飞翔...");
	}
}

package test;

public class Ostrich extends Bird{

	public void fly(){
		System.out.println("我只能在地上奔跑....");
	}
	public static void main(String[] args){
		Ostrich Os = new Ostrich();
		Os.fly();
	}
}

  2.super限定

     当子类方法覆盖了父类方法后,子类对象是无法访问父类中被覆盖的方法的,当可以在子类的方法中调用父类中被覆盖的方法。如果需要在子类方法中调用父类方法,可以使用super(被覆盖的是实例方法)或父类类名(被覆盖的是类方法)作为调用者来调用父类中被覆盖的方法。

     当程序创建一个子类对象时,系统不仅会为该类中定义的实例变量分配内存空间,还会为其从父类继承的所有实例变量分配内存(不管是不是被子类覆盖)。 示例代码如下;


package test;

public class BaseClass {
     public int a = 5;
}

package test;

public class SubClass extends BaseClass{
     public int a=7;
     public void accessOwer(){
    	 System.out.println(a);
     }
     public void accessBase(){
    	 //通过super来访问父类中被覆盖的变量
    	 System.out.println(super.a);
     }
}

  3.子类调用父类的构造器

     可以使用super来显式调用父类的构造器,super调用的格式和this一样;super调用的时候必须放在第一行,所以super与this是不能同时出现的。如果不用super显式调用,子类也必定会在其自己的构造器执行前调用父类的无参构造器,而且一定是从其最开始的父类开始调用。示例代码如下:


package test1;

public class Creature {

	public Creature(){
		System.out.println("Creature的无参构造器");
	}
}

package test1;

public class Animal extends Creature{

	public Animal(String name){
		System.out.println("Animal带一个参数的构造器,"+
	"该动物的名字为:"+name);
	}
	public Animal(String name,int age){
		this(name);
		System.out.println("Animal带两个参数的构造器,"+
				 "其age为:"+ age);
	}
}

package test1;

public class Wolf extends Animal{
     public Wolf(){
    	 super("灰太狼",3);
    	 System.out.println("Wolf的无参构造器");
     }
     public static void main(String[] args){
    	 new Wolf();
     }
}


java面向对象学习笔记(2)