继承
- 被继承的类一般称为“超类”或“父类”,继承的类称为“子类”。当子类继承超类时,不必写出全部的实例变量和方法,只需声明该类继承了的已定义的超类的实例变量和方法即可。超类、子类是继承中非常重要的概念,它们形象地描述了继承的层次关系。继承节省了定义新类的大量工作,可以方便地重用代码。例如,把汽车作为父类,当创建汽车的子类轿车时,品牌、价格、最高时速等属性会自动地被定义,调用刹车方法时会自动调用在汽车类中定义的刹车方法。但一个子类不必非要使用继承下来的属性和方法,一个子类可以选择覆盖已有的属性和方法,或添加新的属性和方法。
- 结构声明:public class 子类名 extends 父类{}
- 一个类只能有一个直接父类,但是可以有多个子类。即Java语言是单继承体系结构。
- 子类中若有父类中没有且自己特有的属性,则称为子类对属性的扩展
- 父类中的构造器是不能被子类继承的,但可以被子类的构造器调用。
在构造方法中使用super(...)是调用父类中的某个与其参数列表相匹配的构造方法。
+ >在构造方法中使用this(...)是用来调用本类中某个与其参数列表相匹配的构造方法
+ 无论是super(...)还是this(...)都必须出现在构造方法的首行。所以它们是不能出现在同一个构造方法的。
- 扩展类时,可以改变父类中方法的行为,这称为方法覆盖,当在子类中编写和父类中某些方法具有相同签名的方法时,就会发生这种情况。覆盖方法可以改变它的行为。要覆盖一个方法,只需在子类中编写新的方法,无需在父类中改变任何内容。如果子类和超类在同一个包中,还可以覆盖缺省访问级的方法。(在父类中存在一个方法,而在子类中也编写了这个方法,那么在子类中的方法会覆盖父类中的那个方法,此技术称为重写override或覆盖、覆写)
- 方法的重写:要覆盖到父类中一般的行为,用子类中更特殊的行为替换它们:
- 发生在子类与父类关系中的一堆方法之间。要求这一对方法要有相同的方法名和参数列表。要求子类的方法访问修饰符一定大于等于父类对应方法的访问修饰符范围。
- private方法时不能被重写的,如果有一个方法时private的,子类也有与其同签名的一个方法,它们时没有任何关系的,子类的方法可以被称为扩展方法而不是重写
- 因为不小心多谢了一个y所以这个方法与父类中的getFinalSalary 就不是同一个方法的概念了,getFinalSalaryy和getFinalSalary是没有任何关系的,在继承体系中,getFinalSalaryy方法是子类中扩展的新方法
public int getFinalSalaryy() {
return getSalary() + bonus;
}
- @Override可以在日后软件的维护过程中帮助程序员进行重写方法关系的保证如果我们不小心把被子类重写过的父类方法签名修改掉,则子类中标有@Overrid的方法就会报编译错误。
- 即使Manger类中没有任何代码,也可以对其进行方法的调用,这些方法来自于其父类Employee,这是继承特性最明显的好处:代码重用。
- 通常要以更抽象的类型声明变量,以更具体得的类型实例化对象,此做法被称为面向接口编程(面向抽象编程)。
- 把子类对象赋值给父类变量是向上转型,是安全的;把父类对象赋值给子类是向下转型,是不安全的。有可能出现java.lang.ClassCastException例如:
// Manager m3 = (Manager)c2;
// long x = 1202834598278238293L;
// int y = (int) x;
- 兄弟类型的对象赋值给其它的兄弟类是不兼容转型是不允许的,不能通过编译
Manager m4 = (Manager)c1;
// 等同于boolean b = (boolean)10;
Employee m2 = new Manager("曹操", 3500, 120000);
Employee c2 = new Coder("张辽", 15000, 10);
、、、、、、、、、
m2.work();
c2.work();
// m2和c2的声明类型都是Employee,但最后两行语句所调用的work方法分别执行的是Manager和Coder类型的特有行为,在调用方法时,Java会执行对象实例类型中的方法
- 如果以父类型声明变量,而用此变量调用子类中的扩展方法,是不会通过编译的,因为在子类中的扩展方法在父类型中是不存在的c2.strike();如果一定要调用子类特有的扩展方法,需要先进行强制转型,此写法很丑陋,可以使后边讲道德接口来细化对象的行为能力
((Coder)c2).strike();
- Cat与Employee类没有任何关系,但是同包的,而Employee类中的实例变量的访问修饰符为package(默认),所以我们可以在Cat类中随意读写Employee及其子类中的实例变量。
- 可以使用proteckted来修饰成员变量,但此关键字的范围其实比package还要大,并不能隐藏成员变量
- 结构声明:public class 子类名 extends 父类{}
- 一个类只能有一个直接父类,但是可以有多个子类。即Java语言是单继承体系结构。
- 子类中若有父类中没有且自己特有的属性,则称为子类对属性的扩展
- 父类中的构造器是不能被子类继承的,但可以被子类的构造器调用。
在构造方法中使用super(...)是调用父类中的某个与其参数列表相匹配的构造方法。
+ >在构造方法中使用this(...)是用来调用本类中某个与其参数列表相匹配的构造方法
+ 无论是super(...)还是this(...)都必须出现在构造方法的首行。所以它们是不能出现在同一个构造方法的。
- 扩展类时,可以改变父类中方法的行为,这称为方法覆盖,当在子类中编写和父类中某些方法具有相同签名的方法时,就会发生这种情况。覆盖方法可以改变它的行为。要覆盖一个方法,只需在子类中编写新的方法,无需在父类中改变任何内容。如果子类和超类在同一个包中,还可以覆盖缺省访问级的方法。(在父类中存在一个方法,而在子类中也编写了这个方法,那么在子类中的方法会覆盖父类中的那个方法,此技术称为重写override或覆盖、覆写)
- 方法的重写:要覆盖到父类中一般的行为,用子类中更特殊的行为替换它们:
- 发生在子类与父类关系中的一堆方法之间。要求这一对方法要有相同的方法名和参数列表。要求子类的方法访问修饰符一定大于等于父类对应方法的访问修饰符范围。
- private方法时不能被重写的,如果有一个方法时private的,子类也有与其同签名的一个方法,它们时没有任何关系的,子类的方法可以被称为扩展方法而不是重写
- 因为不小心多谢了一个y所以这个方法与父类中的getFinalSalary 就不是同一个方法的概念了,getFinalSalaryy和getFinalSalary是没有任何关系的,在继承体系中,getFinalSalaryy方法是子类中扩展的新方法
public int getFinalSalaryy() {
return getSalary() + bonus;
}
- @Override可以在日后软件的维护过程中帮助程序员进行重写方法关系的保证如果我们不小心把被子类重写过的父类方法签名修改掉,则子类中标有@Overrid的方法就会报编译错误。
- 即使Manger类中没有任何代码,也可以对其进行方法的调用,这些方法来自于其父类Employee,这是继承特性最明显的好处:代码重用。
- 通常要以更抽象的类型声明变量,以更具体得的类型实例化对象,此做法被称为面向接口编程(面向抽象编程)。
- 把子类对象赋值给父类变量是向上转型,是安全的;把父类对象赋值给子类是向下转型,是不安全的。有可能出现java.lang.ClassCastException例如:
// Manager m3 = (Manager)c2;
// long x = 1202834598278238293L;
// int y = (int) x;
- 兄弟类型的对象赋值给其它的兄弟类是不兼容转型是不允许的,不能通过编译
Manager m4 = (Manager)c1;
// 等同于boolean b = (boolean)10;
Employee m2 = new Manager("曹操", 3500, 120000);
Employee c2 = new Coder("张辽", 15000, 10);
、、、、、、、、、
m2.work();
c2.work();
// m2和c2的声明类型都是Employee,但最后两行语句所调用的work方法分别执行的是Manager和Coder类型的特有行为,在调用方法时,Java会执行对象实例类型中的方法
- 如果以父类型声明变量,而用此变量调用子类中的扩展方法,是不会通过编译的,因为在子类中的扩展方法在父类型中是不存在的c2.strike();如果一定要调用子类特有的扩展方法,需要先进行强制转型,此写法很丑陋,可以使后边讲道德接口来细化对象的行为能力
((Coder)c2).strike();
- Cat与Employee类没有任何关系,但是同包的,而Employee类中的实例变量的访问修饰符为package(默认),所以我们可以在Cat类中随意读写Employee及其子类中的实例变量。
- 可以使用proteckted来修饰成员变量,但此关键字的范围其实比package还要大,并不能隐藏成员变量
- 结构声明:public class 子类名 extends 父类{}
- 一个类只能有一个直接父类,但是可以有多个子类。即Java语言是单继承体系结构。
- 子类中若有父类中没有且自己特有的属性,则称为子类对属性的扩展
- 父类中的构造器是不能被子类继承的,但可以被子类的构造器调用。
在构造方法中使用super(...)是调用父类中的某个与其参数列表相匹配的构造方法。
+ >在构造方法中使用this(...)是用来调用本类中某个与其参数列表相匹配的构造方法
+ 无论是super(...)还是this(...)都必须出现在构造方法的首行。所以它们是不能出现在同一个构造方法的。
- 扩展类时,可以改变父类中方法的行为,这称为方法覆盖,当在子类中编写和父类中某些方法具有相同签名的方法时,就会发生这种情况。覆盖方法可以改变它的行为。要覆盖一个方法,只需在子类中编写新的方法,无需在父类中改变任何内容。如果子类和超类在同一个包中,还可以覆盖缺省访问级的方法。(在父类中存在一个方法,而在子类中也编写了这个方法,那么在子类中的方法会覆盖父类中的那个方法,此技术称为重写override或覆盖、覆写)
- 方法的重写:要覆盖到父类中一般的行为,用子类中更特殊的行为替换它们:
- 发生在子类与父类关系中的一堆方法之间。要求这一对方法要有相同的方法名和参数列表。要求子类的方法访问修饰符一定大于等于父类对应方法的访问修饰符范围。
- private方法时不能被重写的,如果有一个方法时private的,子类也有与其同签名的一个方法,它们时没有任何关系的,子类的方法可以被称为扩展方法而不是重写
- 因为不小心多谢了一个y所以这个方法与父类中的getFinalSalary 就不是同一个方法的概念了,getFinalSalaryy和getFinalSalary是没有任何关系的,在继承体系中,getFinalSalaryy方法是子类中扩展的新方法
public int getFinalSalaryy() {
return getSalary() + bonus;
}
- @Override可以在日后软件的维护过程中帮助程序员进行重写方法关系的保证如果我们不小心把被子类重写过的父类方法签名修改掉,则子类中标有@Overrid的方法就会报编译错误。
- 即使Manger类中没有任何代码,也可以对其进行方法的调用,这些方法来自于其父类Employee,这是继承特性最明显的好处:代码重用。
- 通常要以更抽象的类型声明变量,以更具体得的类型实例化对象,此做法被称为面向接口编程(面向抽象编程)。
- 把子类对象赋值给父类变量是向上转型,是安全的;把父类对象赋值给子类是向下转型,是不安全的。有可能出现java.lang.ClassCastException例如:
// Manager m3 = (Manager)c2;
// long x = 1202834598278238293L;
// int y = (int) x;
- 兄弟类型的对象赋值给其它的兄弟类是不兼容转型是不允许的,不能通过编译
Manager m4 = (Manager)c1;
// 等同于boolean b = (boolean)10;
Employee m2 = new Manager("曹操", 3500, 120000);
Employee c2 = new Coder("张辽", 15000, 10);
、、、、、、、、、
m2.work();
c2.work();
// m2和c2的声明类型都是Employee,但最后两行语句所调用的work方法分别执行的是Manager和Coder类型的特有行为,在调用方法时,Java会执行对象实例类型中的方法
- 如果以父类型声明变量,而用此变量调用子类中的扩展方法,是不会通过编译的,因为在子类中的扩展方法在父类型中是不存在的c2.strike();如果一定要调用子类特有的扩展方法,需要先进行强制转型,此写法很丑陋,可以使后边讲道德接口来细化对象的行为能力
((Coder)c2).strike();
- Cat与Employee类没有任何关系,但是同包的,而Employee类中的实例变量的访问修饰符为package(默认),所以我们可以在Cat类中随意读写Employee及其子类中的实例变量。
- 可以使用proteckted来修饰成员变量,但此关键字的范围其实比package还要大,并不能隐藏成员变量