九. 方法重载(overload)
有时侯,类的同一种功能有多种实现方式,换句话说,有很多相同名称的方法,参数不同。 这给用户对这种功能的调用使用提供了很大的灵活性。 例如:Test类中要求有两个方法: public void print(int i){ System.out.println("i = "+i); } public void print(String s){ System.out.println("s = "+s); } 对于类的方法(包括从父类中继承的方法), 如果有两个方法的方法名相同,但参数不一致, 那么可以说,一个方法是另一个方法的重载方法。这种现象叫重载。 重载必须满足以下条件: 1) 方法名称相同。 2) 参数列表不同(参数类型、个数和顺序)。 注意: 返回类型可以不相同。 在一个类中不允许定义两个方法名相同,并且参数也完全相同的方法。 因为假如存在这样的两个方法,Java虚拟机在运行时就无法决定到底执行哪个方法。 参数是指参数的类型、个数和顺序。十. 创建和初始化对象
按照前面讲述的定义类的形式、定义方法的形式,构建好类了之后, 程序要真实的运行,还是得通过对象的交互来完成。 创建好了类,只是创建了构建对象的模板。 接下来,我们可以通过new操作符,快速地构建出对象。使用new有以下作用有以下几步: 1.为对象分配内存空间,将对象的实例变量自动初始化默认值; 2.如实例变量显示初始化,将初始化值赋给实例变量(把默认值覆盖掉); 3.调用构造方法; 4.返回对象的地址值;十一. 构造方法 (构造器/构造函数/构造方法) 1. 定义:
. 构造方法的名字和类的名字相同 . 没有返回类型,有返回类型的构造器就变成了普通方法。 2. 调用时刻: 在创建对象的时候调用; 注意:是先创建对象,然后初始化对象中的属性值,最后在调用构造器 3. 作用: 可以让我们在创建对象的时候做一些对象中数据的初始化工作.(因为在new的后面就是写的构造器) new Student(); new Student("tom",age); 4. 构造方法的调用: 构造方法只能通过以下方式被调用: . 当前类的其他构造方法通过this语句调用它; . 当前类的子类的构造方法通过super语句调用它; . 在程序中通过new语句调用它;十二. 构造方法重载
当通过new语句创建一个对象时,在不同的条件下,对象可能会有不同的初始化行为。 例如对于公司新来的一个雇员,在一开始的时侯,有可能他的姓名和年龄是未知的, 也有可能仅仅他的姓名是已知的,也有可能姓名和年龄都是已知的。 如果姓名是未知的,就暂且把姓名设为“无名氏”,如果年龄是未知的,就暂且把年龄设为-1. 可通过重载构造方法来表达对象的多种初始化行为。 在一个类的多个构造方法中,可能会出现一些重复操作。 为了 提高代码的可重用性,Java语言允许在一个构造方法中,用this语句来调用另一个构造方法。使用this语句来调用其他构造方法时,必须遵守以下语法规则:
1.假如在一个构造方法中使用了this语句,那么它必须作为构造方法的第一条要执行的语句(不考虑注释语句)。
public Employee() { String name="无名氏"; this(name); //编译错误,this语句必须作为第一条语句 } public Employee(String name) { String name=name; }2.只能在一个构造方法中用this语句来调用类的其他构造方法,而不能在实例方法中用this语句来调用类的其他构造方法;
3.只能用this语句来调用其他构造方法,而不能通过方法名来直接调用构造方法。
public Employee() { Employee(name); //编译错误,要使用this关键字来调用 String name="无名氏"; } public Employee(String name) { String name=name; }十三. 默认的构造方法
构造方法可分为两种: 1) 隐含的默认构造方法(无参构造器); 2) 程序显示定义的构造方法; 在Java语言中,每个类至少有一个构造方法。为了保证这一点,如果用户定义类中没有提供任何构造方法, 那么在运行的时候JVM将自动提供一个隐含的默认构造方法。 该构造方法没有参数,用public修饰,而且方法体为空,格式如下: public ClassName(){} //隐含的默认构造方法 在程序中也可以显示地定义默认构造方法。 如果类中显式定义了一个或多个构造方法,那么Java语言便不再分配隐含的默认构造方法。举例: public class Sample{ public Sample(int a) { System.out.println("My Constructor"); } } 创建Sample类对象的语句: Sample s1 = new Sample(); //编译出错 Sample s2 = new Sample(1); //合法的十四. 子类 1. 通过生活中的例子推出Java中继承;
什么是继承呢?生活中不乏这样的例子, 张老头有个儿子张小头,张老头健在的时侯,张小头继承了张老头的坏脾气,国字脸,八字脚。 张小头只有亲生爸爸张老头,张老头却有包括张小头在内的多个子女。 Java中类与类之间也有生活中类似的继承关系。 在Java类继承关系中,对应于父亲的类叫父类,对应于儿子的类叫子类。 父子类间的继承关系也叫“is a”关系。 这种关系通过类声明上的extends关键字体现。 一个子类只有一个父类,一个父类可有多个子类。 2. 为什么要继承? . 站在巨人的肩膀上;通过继承,我们可以快速构建出一个带有丰富功能的新类; 有了张老头,张小头年纪轻轻就可以买上上百万的新房; . 不修改源代码,修改既有类的行为; 通过继承,在子类中构建父类中一样的方法,可以改变父类方法的行为。 张老头没有考上大学,通过张小头圆了其上大学的梦。 3. Object类简略介绍 所有的Java类都直接或间接地继承了java.lang.Object类 。Object类是所有Java类的祖先,在这个类中定义了所有的Java对象都具有相同行为。十五. 继承
子类继承了父类的属性和方法: 1) 父子类同包,子类继承父类中public、protected和默认访问级别的成员变量和成员方法; 2) 父子类不同包,子类继承父类中public、protected的成员变量和成员方法; 那么继承有哪些细节呢? 1、构造器不能被继承 2、方法和实例变量可以被继承 3、子类构造器隐式地调用父类的默认无参构造器; 4、如果父类中没有定义无参构造器,只定义了有参构造器, 那么子类构造器则必须显式地调用父类的有参构造器(通过super(…)),且必须放置在第一条语句,否则会有语法错误。 5、this()和super()在构造器中都必须为第一条语句,两者不能同时出现。 6、当一个子类继承了一个父类后,父类中所有的字段和方法都被子类继承拥有,子类可以任意的支配使用,每个子类对象中都拥有了父类中的所有字段。当构造一个子类的实例对象时,该对象的实例变量包括了子类本身以及父类中的所有实例变量,实例方法也包括了子类和父类中的所有实例方法。 7、子类构造器用来初始化子类中所有的实例变量,而父类构造器super(实参)用来初始化父类中所有的实例变量。 所以在堆中为子类实例对象分配的内存区域中包括了子类和父类中所有初始化后的实例变量十六. super关键字
1. 为什么要使用super关键字? 1)子类中要访问父类方法或变量。 2) 子类中调用父类的构造器 2. 使用注意事项: a. 只能在构造方法或实例方法内使用super关键字, 在静态方法和静态代码块内不能使用super关键字。 b. 在子类构造方法中如没有使用this关键字,会隐式调用父类的无参构造方法; class Father() { public Father() { //这里第一行隐含一句代码: super(); System.out.println("In Father()"); } } class Son extends Father { } public class Test { public static void main(String[] args) { new Son(); //打印输出 In Father() } } ----------------------------------------------------------------------- class Father() { public Father() { System.out.println("In Father()"); } } class Son extends Father { public Son() { System.out.println("In Son()"); } } public class Test { public static void main(String[] args) { new Son(); //打印输出 In Father() // In Son() } } ----------------------------------------------------------------------- class Father() { public Father(String name) { System.out.println("In Father() " + name); } } class Son extends Father { public Son() { System.out.println("In Son()"); } } public class Test { public static void main(String[] args) { new Son(); //编译出错, 子类会隐式调用父类中无参构造方法,而此时父类中不存在无参构造方法。 } } ----------------------------------------------------------------------- class Father() { public Father(String name) { System.out.println("In Father() " + name); } } class Son extends Father { public Son() { super("zs"); System.out.println("In Son()"); } } public class Test { public static void main(String[] args) { new Son(); //打印输出: //In Father() zs //In Son() } } ----------------------------------------------------------------------- class Father() { public Father() { System.out.println("In Father()"); } public Father(String name) { System.out.println("In Father(String name)"); } } class Son extends Father { public Son() { this("zs"); System.out.println("In Son()"); } public Son(String name) { System.out.println("In Son(String name)"); } } public class Test { public static void main(String[] args) { new Son(); //打印输出: //In Father() //In Son(String name) //In Son() } } c. 构造方法中this(...)和super(...)不能同时出现;