继承
封装
对象代表什么,就得封装对应的数据,并提供数据对应的行为
继承
Java中提供一个关键字extends,用这个关键字,我们可以让一个类和另外一个类建立起继承关系
public class Student extends Person{}
Student称为子类(派生类) ,Person称为父类(基类或超类)
构建基础的核心:
1.共性内容抽取
2.子类是父类的一种
书写代码:从上往下
父类的父类Animal
package com.cjj.a01extendsDemo01;
public class Animal {
//权限修饰符
//private:子类无法访问
//私有,只能在本类中访问
//注意事项
//子类只能访问父类中非私有的成员
public void eat(){
System.out.println("吃饭");
}
public void drink(){
System.out.println("喝水");
}
}
猫:父类
package com.cjj.a01extendsDemo01;
public class Cat extends Animal{
public void catchMouse(){
System.out.println("抓老鼠");
}
}
狗:父类
package com.cjj.a01extendsDemo01;
public class Dog extends Animal{
public void protectHome(){
}
}
猫:子类
package com.cjj.a01extendsDemo01;
public class Ragdoll extends Cat{
}
猫:子类
package com.cjj.a01extendsDemo01;
public class ChineseLiHua extends Cat{
}
狗:子类
package com.cjj.a01extendsDemo01;
public class Huskie extends Dog{
public void breakHome(){
System.out.println("哈士奇在拆家");
}
}
狗:子类
package com.cjj.a01extendsDemo01;
public class Teddy extends Dog{
public void touch(){
System.out.println("泰迪在蹭老吊的腿");
}
}
使用继承的好处
可以把多个子类中重复的代码抽取到父类中了,提高代码的复用性。
子类可以在父类的基础上,增加其他的功能,使子类更加强大。
什么时候使用继承
当类与类之间,存在相同(共性)的内容,并且满足子类是父类的一直,就可以考虑使用继承,来继承代码。
继承的特点
java只支持单继承:一个子类只能继承一个父类
不支持多继承:一个子类不能同时继承多个父类
但支持多层继承:子类A继承父类B,父类B可以继承父类C
每一个类都之间或间接的继承object
子类只能访问父类中非私有的成员
public class A extends B{}
//默认继承
public class Object{}
子类到底能继承父类中的那些内容
构造方法 非私有 不能 private不能
构造方法是否可以被继承:父类的构造方法不能被子类继承
package com.cjj.a02extendsdemo02;
public class Test {
public static void main(String[] args) {
//利用空参构造创建子类对象
Zi z1 = new Zi();
//利用带参构造子类对象
Zi z2 = new Zi("zhangsan",23);//会出现报错:Create constructor,
}
}
class Fu{
String name;
int age;
public Fu(){
}
public Fu(String name, int age) {
this.name = name;
this.age = age;
}
}
class Zi extends Fu{
//如果一个类中没有构造方法,虚拟机会自动添加一个空参构造
}
成员变量 非私有 能 private 能
成员变量是否可以被继承 能
private修饰的能继承但是不可以直接使用
成员方法 非私有 能 private 不能
继承中:成员变量的访问特定
就近原则:现在局部位置找,本类成员位置找,父类成员位置找,逐级往上
package com.cjj.a03extendsDemo03;
public class Test {
public static void main(String[] args) {
Zi z = new Zi();
z.zishow();
}
}
class ye{
String name = "ye";
}
class fu extends ye{
String name = "fu";
}
class Zi extends fu{
String name = "zi";
public void zishow(){
String name = "zishow";
System.out.println(name);//就近原则
System.out.println(this.name);//到本类的成员中找
System.out.println(super.name);//直接从父类找
}
}
继承中:成员方法的访问特点
直接调用满足就近原则:谁离我近,我就用谁
super调用,直接访问父类
package com.cjj.a05extendsDemo05;
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
s1.lunch();
OverseaStudent s2 = new OverseaStudent();
s2.lunch();
}
}
class Person{
public void eat(){
System.out.println("吃米饭,吃菜");
}
public void drink(){
System.out.println("喝白开水");
}
}
class OverseaStudent extends Person{
public void lunch(){
this.eat();
this.drink();
super.eat();
super.drink();
}
public void eat(){
System.out.println("吃意大利面");
}
public void drink(){
System.out.println("喝冰水");
}
}
class Student extends Person{
public void lunch(){
//先在本类中查看eat和drink方法,就会调用子类的,如果没有,就会调用从父类中继承下来的eat和drink方法
eat();
drink();
//直接调用父类
super.eat();
super.drink();
}
}
方法的重写:当父类的方法不能满足子类现在的需求时,需要进行方法重写
书写格式:在继承体系中,子类出现了和父类一模一样的方法声明,我们就称这个子类就是方法的重写
@Override重写注释:1.@Override是放在重写后的方法上,校验子类重写时语法是否正确。
2.加上注解后如果有红色波浪线,表示语法错误
3.建议重写方法都加上@Override注解,代码安全,优雅!
//应用场景:当父类中的方法,不能满足子类现在的需求时,我们就需要把这个方法进行重写
//注意:子类重写的方法上面需要加上@Override
@Override
public void eat(){
System.out.println("吃意大利面");
}
@Override
public void drink(){
System.out.println("喝冰水");
}
}
如果发生了重写,则会覆盖。
方法重写注意事项和要求:
1.重写方法的名称,形参列表必须与父类中的一致
2.子类重写父类方法时,访问权限子类必须大于等于父类
3.子类重写父类方法时,返回值类型子类必须小于等于父类
4.建议:重写的方法尽量与父类保持一致
5.私有方法不能被重写
6.子类不能重写父类的静态方法,如果重写会报错
7.只有添加到虚方法表中的方法才能被重写
继承中:构造方法的特点
1.父类中的构造方法捕获被子类继承
2.子类当中所有的构造方法默认先访问父类中的无参构造,再执行自己
为什么:1.子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
2.子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化
怎么调用父类构造方法?
1.子类构造方法的第一行语句默认都是:super(),不写也存在,且必须在第一行
2.如果想调用父类有参构造,必须手动写super进行调用。
package com.cjj.a07extendsDemo07;
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
System.out.println("父类的无参构造");
}
}
package com.cjj.a07extendsDemo07;
public class student extends Person {
public student() {
//子类构造方法中有隐藏的super()去访问父类的无参构造
super();
System.out.println("子类的无参构造");
}
public student(String name, int age) {
super(name,age);
}
}
package com.cjj.a07extendsDemo07;
public class Test {
public static void main(String[] args) {
//创建学生对象
student s = new student("zhansgna",23);
System.out.println(s.name+","+s.age);
}
}
总结:
1.子类不能继承父类的构造方法,但是可以通过super调用
2.子类构造方法的第一行,有一个默认的super()
3.默认先访问父类中的无参构造,在执行自己
4.如果想要方法文父类有参构造,必须手动书写
this,super使用总结
this:理解为一个变量,表示当前方法调用者的地址值
super:代表父类存储空间
public class Student {
String name;
int age;
public void show(Student this){
sout(this.name+","+this.age)
}
}
关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
this | this.成员变量 访问本类成员变量 | this.成员方法(···) 访问本类成员方法 | this(····) 访问本类构造方法 |
super | super.成员变量 访问父类成员变量 | super.成员方法(····) 访问父类成员方法 | super(·······) 访问父类构造方法 |
小结
什么是继承,继承的好处?
继承是面向对象三大特征之一,可以让类与类之间产生父子关系。
可以把多个子类中重复的代码抽取到父类中,子类可以直接使用,减少代码冗余,提高代码的复用性
继承的格式
public class 子类 extends 父类{}
继承后子类的特点
子类可以得到父类的属性和行为,子类可以使用。
子类可以在父类的基础上新增其他功能,子类更强大。