Java类必须包含一个或一个以上的构造器,使用构造器最大的好处就是在创建对象时,对类的Field进行初始化(当创
建一个对象的时候,系统为这个对象的Field进行默认初始化,如果是基本类型如数值型赋值为0,如果是引用类型的
Field赋值为null),如以下代码:
public class Teacher { private String name; private int age; public Teacher(){ } public Teacher(String name,int age){ this.name=name; this.age=age; } @Override public String toString() { return "name="+name+"\nage="+age; } }
以上代码提供了一个自定义的构造器,我们通过这个构造器进行初始化操作。
下面我们来看看如何使用自定义的构造器来创建对象并进行初始化:
public class Main { public static void main(String[] args) { Teacher teacher=new Teacher("Bill",25); System.out.println(teacher.toString()); } }
输出结果:
name=Bill
age=25
在这里值得指出的是:当我们调用构造器时,系统会先为该对象分配内存空间,并且为这个对象执行默认的初始化操
作,也就是,在系统开始执行构造器之前系统已经创建了一个对象,只是这个对象还不能被外部访问,只能在该构造
器中通过this来引用。
我们前面提到过,当我们自己提供构造器时,系统就不再提供默认的构造器,如果需要,可以自己定义无参的构造
器。
在前面我们知道在同一个类中相同的方法名,不同的形参列表,称为方法的重载。构造器也是如此,多个构造器的形
参列表不同,称作构造器的重载(构造器的名字必须和类名保持一致)。
类的继承是面向对象的三大特征之一(前面讲过封装),继承是实现软件复用的重要手段,我们学习的Java具有单继
承的特点,也就是每一个子类只有一个直接父类。继承可以通过extends关键字来实现,实现继承的类被称为子类,
被继承的类称为父类(基类、超类)
以下是继承的语法格式:
public class MathTeacher extends Teacher { }
继承到底有何作用,我们来看下下面的代码:
public class Teacher { public String name; public int age; public Teacher(){ } public Teacher(String name,int age){ this.name=name; this.age=age; } @Override public String toString() { return "name="+name+"\nage="+age; } }
为方便,我们把Teacher类的Field的访问权限更改为public,关于访问控制符的说明请参看(Java面向对象笔记2)
接着在编写主入口:
public class Main { public static void main(String[] args) { MathTeacher teacher=new MathTeacher(); teacher.name="bill"; teacher.age=25; System.out.println(teacher.toString()); } }
输出结果:
name=Bill
age=25
在上面我们定义了一个空的MathTeacher类,并继承Teacher这个类,在main方法中,创建了MathTeacher对象,并
访问和赋值这个对象的name和age,从这里可以看出,MathTeacher对象也具有了Teacher实例Field和toString方法。
子类扩展了父类,子类就是一个特殊的父类,通常情况,子类总是以父类为基础,额外增加新的Field和方法。但有一
种情况例外,比如鸟都有飞行这个方法,其中鸵鸟也是鸟,但它的飞行方式与其它的鸟不同,因此我们需要重写鸟的
飞行方法,来满足鸵鸟的飞行方式,代码如下:
定义一个鸟的类
public class Bird { public void fly(){ System.out.println("在天空飞翔"); } }
接着定义一个鸵鸟的类
public class Ostrich extends Bird { @Override public void fly() { System.out.println("在地上跑"); } }
最后创建鸵鸟这个对象
public class Main { public static void main(String[] args) { Ostrich ostrich=new Ostrich(); ostrich.fly(); } }
输出结果:
在地上跑
从上面我们可以看出执行fly这个方法已经不再是Bird类的fly方法了,而是执行了Ostrich类的fly方法。这种子类包含与
父类同名方法的现象称作方法重写,也被称为覆盖。方法的
重写要遵循“两同两小一大”,“两同”是值方法名相同、形参列表相同;“两小”指的是子类方法返回值类型比父类方法返
回值类型更小或相等,子类方法声明抛出的异常应比父类方法声明抛出的异常更小或相等;“一大”指的是子类方法的
访问权限应比父类方法的访问权限更大或相等。
在子类中我们可以通过super来调用父类被覆盖的实例方法,super是Java提供的一个关键字,用于限定该对象调用它
从父类继承得到的Field或方法,super不能出现在static修饰的方法中。
在子类的构造器中可以通过super来调用父类构造器的初始化代码,如以下代码:
public class Bird { private int weight; public Bird(int weight){ this.weight=weight; } public void fly(){ System.out.println("在天空飞翔"); } }
public class Ostrich extends Bird { public Ostrich(int weight) { super(weight); } @Override public void fly() { System.out.println("在地上跑"); } }
public class Main { public static void main(String[] args) { Ostrich ostrich=new Ostrich(25); ostrich.fly(); } }
上面的程序中,就是通过super调用父类的构造器并进行初始化(值得注意的是,this 和super不会同时出现 )。其
实,不管我们是否使用super调用来执行父类构造器的初始化代码,子类构造器总会调用父类构造器一次。也就是当
调用子类构造器来初始化子类对象时,父类构造器总会在子类构造器之前执行。
转载请注明出处:http://blog.csdn.net/hai_qing_xu_kong/article/details/43866163
情绪控_