面向对象之继承
主要通过extends来实现,子类对父类的继承,实际上是子类对父类的扩展,子类是一种特殊的父类。
子类继承父类:可以调用父类非私有的的成员(成员变量、成员方法)
高内聚低耦合是程序设计的追求。
耦合:两个(或更多)模块相互依赖对方(齿轮之间耦合转动,只要一个出错,另一个就无法正常工作)
内聚:模块内部结构紧密,独立性强。
案例1:动物类继承
main方法
package itcast.demo1;
public class TestAnimal {
public static void main(String[] args) {
Dog h = new Dog();
h.eat("小黑");
h.watch();
Pig g = new Pig();
g.snore();
}
}
Animal父类
ackage itcast.demo1;
public class Animal {
// 成员变量
private String name;
private int age;
private String sex;
// 构造方法
public Animal() {
}
public Animal(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 成员方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public void eat(String name){
this.name = name;
System.out.println(name +"干饭");
}
}
动物子类
package itcast.demo1;
public class Dog extends Animal{
//成员方法
public void watch(){
System.out.println("发动看家技能....");
}
}
package itcast.demo1;
public class Pig extends Animal{
public void snore(){
System.out.println("睡大觉");
}
}
当子类存在自己特殊行为或是特点时,写到子类当中即可
优点:功能复用,便于扩展新功能,结构清晰,简化认识,易于维护
缺点:打破封装性,子类的实现细节暴露在父类当中,具有高耦合性,类与类之间相互依赖性较高
子父类中定义了同名的成员变量,如何使用?用到super方法
package itcast.demo2;
public class Test {
public static void main(String[] args) {
c a = new c();
a.price();
}
}
package itcast.demo2;
public class p {
int price = 20;
public p() {
}
public p(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
package itcast.demo2;
public class c extends p{
int price = 10;
public void price(){
int price = 5;
System.out.println(price);
System.out.println(this.price);
System.out.println(super.price);//打印父类的成员变量
/*但是父类中如果有private修饰的成员变量,这里就不能打印*/
Person c = new Person();
c.show4();
}
}
继承关系中成员变量使用
- 查找变量的原则:就近原则
- 查找变量的顺序:局部变量→成员变量→父类→更高的父类…Object
- 访问父类变量的方式:super.xxx
- super:当前对象父类的引用
- 对象初始化顺序:先初始化父类内容,再初始化子类内容
继承关系中成员方法使用
- 查找方法的原则:就近原则
- 查找方法的顺序:本类→父类→更高的父类…Object
- 访问父类变量的方式:super.父类方法名();
- 定义重名方法的前提:父类功能不能满足现实需求,扩展父类功能;父类功能已过时,重新实现父类功能。
子父类的构造方法——无参构造、带参构造
package itcast.demo4;
/*测试类
子类所有的构造方法第一行都会有一个默认的super()用来访问父类的无参构造方法,写不写都可以
若父类是带参构造,通过super(参数)访问父类的带参构造
* */
public class Test {
public static void main(String[] args) {
Worker a =new Worker();
}
}
无参构造
package itcast.demo4;
// 父类
public class Person {
public Person(){
System.out.println("Person类 空参构造");
}
}
package itcast.demo4;
//子类
public class Worker extends Person{
public Worker(){
super();//这一行,写不写都存在
System.out.println("Worker类 空参构造");
}
}
直接运行的结果
Person类 空参构造
Worker类 空参构造
带参构造
package itcast.demo4;
// 父类
public class Person {
public Person(String name){
System.out.println("Person类 带参构造 "+name);
}
}
package itcast.demo4;
//子类
public class Worker extends Person{
public Worker(){
super("大橘");
System.out.println("Worker类 空参构造");
}
}
运行结果
Person类 带参构造 大橘
Worker类 空参构造
方法重写
子类当中出现与父类方法定义相同的方法现象(方法名、参数列表、返回值类型都相同)
父类中私有的方法无法重写;子类方法的访问权限不能小于父类方法,且不能抛出比父类方法更大的异常。
常用于重名父类方法的情形。
四大修饰符权限的修饰范围从小到大分别是:private、默认(啥也不写)、protected、public
方法重载:同一个类中方法名相同,其他无关紧要
package itcast.demo4;
import itcast.demo2.Woker0;
/*测试类
本类 同包下的子类 不同包下的子类 不同包下的无关类
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
* */
public class Test {
public static void main(String[] args) {
Worker a =new Worker();
a.show2();a.show3();a.show4();
Woker0 b = new Woker0();
b.show3();b.show4();
// 不同包下的无关类写在demo2的继承p的c子类中调用Person类的show4
}
}
package itcast.demo4;
// 父类,这里也是可以写main方法的
public class Person {
private void show1(){
System.out.println("show1 private");
}
void show2(){
System.out.println("show2 default");
}
protected void show3(){
System.out.println("show3 protected");
}
public void show4(){
System.out.println("show4 public");
}
public static void main(String[] args) {
Person c = new Person();
c.show1();c.show2();c.show3();c.show4();
}
package itcast.demo4;
//子类
public class Worker extends Person{
}
总结
private:给自己用
default:给同一个包用
protected:给子类用(不管是不是同一个包)
public:给大家用
继承特点
- 单类继承(但是可以多层继承 父类(子类(子类(…))));
- 多接口继承 (接口A extends 接口B,接口C,接口D,…)
- 父类私有无法继承
- 构造方法不能被继承,只能被调用
- 子类符合"is a"父类的情况才能使用继承,其他情况可以但不建议。“Apple is a fruit.”