什么是继承?
关键字extends,用这个关键字,可以让一个类和另一个类建立起父子关系
- 继承的特点:子类能继承父类的非私有成员(成员变量、成员方法)
- 继承后对象的创建:子类的对象时由子类、父类共同完成的
代码演示:
public class A {public int i; //公开变量和方法public void print1(){System.out.println("print1");}private int j; //私有变量和方法private void print2(){System.out.println("print2");}
}
java中的继承指的是能否直接使用,不能继承=不能直接使用≠子类没有这个变量,所以若子类想访问父类的私有成员,则需要父类写好get,set方法,私有方法同理
public class Test {public static void main(String[] args) {B b = new B();b.setJ(1);System.out.println(b.getJ());}
}
- 子类的对象是由父类和子类俩张设计图设计出来的
- 继承就是用extends关键字让一个类和另一个类建立起一种父子关系
- 带继承关系的类创建的对象可以直接访问子类和父类中的公开成员变量和成员方法
使用继承有什麽好处?
- 减少重复代码的编写,提高代码复用性
就像提公因式,把多个类里面重复的代码提取到一个父类里面,然后其它类继承父类就可以直接使用这些重复代码,不需要再重新编写
单继承
- java中的类是单继承的(只能有一个父类),不支持多继承,但是支持多层继承
- 多层继承:比如b继承了a类,c继承了b类,这就叫多层继承,java是支持多层继承的
假如多继承,俩个父类有同名变量或方法,就不知道该去使用谁的了
Object类
Object类是所有类的老祖宗,我们写的任何一个类其实都是Object的子类或子孙类
所以其实只创建一个类,里面不写任何方法,但是通过这个类创建的对象也会有一些默认就有的方法,这些方法就是继承Object类
那么,既然不支持多继承,写新类的时候继承了一个类是不是就不会继承Object类了?当然不,即使信类没有继承Object类,父类也会继承,即使父类也没有继承,爷类也会继承,一直网上追溯,还是会继承到Object类的
方法重写
什麽是方法重写?
当子类觉得父类中某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类这个方法,这就是方法重写
重写后,方法的访问,java会遵循就近原则
方法重写的注意事项
- 重写小技巧:使用Override注解,他可以指定java编译器,检查我们方法重写的格式是否正确,
- 代码可读性也会更好子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限( public> protected> 缺省 )。
- 重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
- 私有方法、静态方法不能被重写,如果重写会报错的。
Override注解,严格要求重写方法格式:
方法重写常见应用场景
重写toString方法
toString方法是Object类里面的方法,当直接输出变量的时候就会默认调用toString方法,toString方法默认是输出该对象地址,重写toString方法就可以改变直接输出对象时的内容
代码演示:
重写toString:
public class Student {@Overridepublic String toString(){ //重写toStringreturn "大家好,我是Student";}
}
Test:
public class Test {public static void main(String[] args) {Student s = new Student(); //定义对象System.out.println(s); //直接输出对象}
}
运行结果:
子类访问其它成员
- 在子类方法中访问其它成员(成员变量、成员方法),是依照就近原则的
什麽是就近原则?
顾名思义,就是谁离得近访问谁:局部变量 > 子类成员变量 > 父类成员变量
那么如果要在局部变量、子类成员变量、父类成员变量皆同名的情况下去访问子类成员变量和父类成员变量该怎麽做?
该情况下:
- 想访问成员变量:this.子类成员变量名
- 想访问父类成员变量:super.父类成员变量名
关于成员方法依旧是就近原则:重写成员方法 > 父类成员方法
如果坚持想访问父类方法:super.父类方法名
子类构造器的特点
- 子类的全部构造器,都会先调用父类的构造器,再执行自己
代码演示:
class a{public a(){System.out.println("父类a无参构造器执行");}
}class b extends a{public b(){System.out.println("子类b无参构造器执行");}
}public class Test {public static void main(String[] args) {b b1 = new b();}
}
运行结果:
构造器不管写不写都会默认存在一句super();//调用父类无参构造器
子类构造器为什么要调用父类构造器?
因为使用了继承,子类使用了俩个类的设计图来设计,也就是说子类可能有一些成员变量被拆分到父类里面,因此需要调用父类构造器把父类里面的成员变量先进行赋值