java-继承
概念:继承是从已有类中派生出新的类,新的类吸收已有类中的属性和行为,并且可以扩展新的能力。我们把被继承的类称为父类继承父类的类称为子类,简单来说子类继承了父类的所有属性和方法,并且子类中可以添加新的属性和方法。
继承语法
//父亲
//儿子 继承 继承的格式是怎么样写的
//多态
class Fu{
//公共代码(财产)
}
//extends 继承
class Zi extends Fu{
}
public class Demo02 {
}
案例:
//子类继承父类之后拥有了父类中的非私有属性和方法
//父类
class Person{
String name;
int age;
public void eat() {
System.out.println("吃饭...");
}
}
//学生类
class Student extends Person{
}
//老师类
class Teahcer extends Person{
}
//护士类
class Nurse extends Person{
}
//测试类
public class TestDemo01 {
public static void main(String[] args) {
//如果我们遇到多个类有相同的属性和方法的时候
//我们可以把这些相同的属性和方法放到一个独立的类中
//其它的类只要用extends关键字来继承就可以了
Nurse nurse=new Nurse();
System.out.println(nurse.name);
System.out.println(nurse.age);
nurse.name="苍老师";
nurse.age=38;
System.out.println(nurse.name);
System.out.println(nurse.age);
nurse.eat();
Student s1=new Student();
s1.name="奥利给";
s1.age=20;
System.out.println(s1.name);
System.out.println(s1.age);
s1.eat();
}
}
继承的优点
提高了代码的复用性,提高了代码的维护性,让类产生了关系,是多态的前提
缺点:
让类与类之间产生了关系 继承的弊端让类的耦合性增强了。
继承的限制:
限制一 一个类只能继承一个父类。
//例一
Class A{}
Class B{}
Class C extends A,B{}//是错误的方法
为了实现一个类继承多个类的属性和功能以上方法的写法是错误的,一个类想继承多个类的功能可以用下面方法
//例二
Class A{}
Class B extends A{}
Class C extends B{}
这样C类就同时继承了B类和A类的方法及属性。这种操作称为多层继承
因此java之中只允许多层继承(例二)不允许多重继承(例一)
限制二
子类在继承父类的时候,理论上会继承父类之中的所有属性及方法,但是需要注意,对于所有的非私有(no private)操作属于显式操作(可以直接使用对象操作),而所有的私有操作属于隐式操作(需要间接完成)。
限制三
在继承中,如果要实例化子类对象,会默认先调用父类构造,为父类之中的属性初始化,之后再调用子类构造,为子类之中的属性初始化。
Class A {
public A(){
System.out.print("1111111111")
}
}
Class B extends A {
public B(){
System.out.print("2222222222")
}
}
public class Testdemo{
public static void main(String[] args) {
}
}
//输出结果
/*1111111111
2222222222*/
继承中成员变量的关系
子类中的成员变量和父类中的成员变量名称一样时,变量就近原则。
先查看子类方法的局部范围找,有就使用,否则在子类的成员方法找,有就是用,否则在父类的成员范围找
super关键字
super和this用法类似,super代表父类存储空间的标识(可以理解为父类引用)
this代表当前对象,super代表父类对象
调用成员变量
this.成员变量(参数) 调用当前对象变量
super.成员变量(参数) 调用的父类对象的变量
调用成员方法
this.成员方法(参数) 调用当前对象方法
super.成员方法(参数) 调用的父类对象的方法
调用构造方法
this(…) 调用本类的构造方法
super(…)调用父类的构造方法
class Father{
//成员变量
public int num=10;
public void method() {
//局部变量
int num=50;
}
public void say() {
System.out.println("乖乖...");
}
}
class Son extends Father{
public int num=30;
public int num2=20;
public void say() {
System.out.println("爸爸...");
}
public void aa() {
//this.say();
super.say();
}
public void show() {
int num=60;
System.out.println(num);//局部变量 60
System.out.println(this.num);//成员变量 30
System.out.println(super.num);//super的关键字访问父类的成员 10
}
}
public class ExtendsDemo01 {
public static void main(String[] args) {
Son son=new Son();
son.aa();
}
}
继承中构造方法的关系
子类所有的构造方法会默认访问调用父类无参的构造器, 因为子类对象继承父类对象的属性和方法,所以在子类初始化之前,一定要对父类进行初始化。 在每个类每一个构造方法中第一行有效代码默认都是super()。super关键字必须写在构造方法有效代码第一行,因为如果不是第一行就可能对父类的数据进行多次初始化。
class Father{
int age;
public Father() {
age=100;
System.out.println("父类的无参构造器");
}
public Father(int age) {
this.age=age;
System.out.println("父类的有参构造器");
}
}
//1.子类所有的构造方法会默认访问调用父类无参的构造器
//为什么? 因为子类对象继承父类对象的属性和方法
// 所以在子类初始化之前,一定要对父类进行初始化
// 在每个类每一个构造方法中第一行有效代码默认都是super()
// super关键字必须写在构造方法有效代码第一行
//1.构造方法是不能继承的
//2.不管调用的是子类的无参构造还是有参构造,都会先执行父类的无参构造器
//3.但是子类的构造器人为编写代码访问父类的有参构造器
class Son extends Father{
public Son() {
//无法调用父类的无参构造器
super();
int x=0;
}
public Son(int age) {//int age=20
super(age);
System.out.println("子类有参");
}
}
public class ExtendDemo {
public static void main(String[] args) {
Son son=new Son(20);
}
}
重写
概念: 重载 (override) 一个类中,方法名相同,参数列表不同(参数的个数或者类型不同),和返回值没有关系
重写(overload) 继承关系中,子类去重新写一遍父类已经有的方法,方法的声明要一致,包括返回值类型
使用特点:如果方法名不同,就调用对应的方法
如果方法名相同,最终使用的是子类自己的方法
class Phone{
public void call(String name) {//String name=奥利给
System.out.println("给"+name+"打电话");
}
}
class HuaWei extends Phone{
//重新写一遍
public void call(String name) {//String name=奥利给
//调用父类的call方法
super.call(name);//奥利给
System.out.println("看视频...");
}
}
public class Demo02 {
public static void main(String[] args) {
HuaWei huaWei=new HuaWei();
huaWei.call("奥利给");
}
}
方法重写的注意事项
父类中私有方法不能重写 因为父类私有方法更本没有办法继承;
子类在重写父类的时候 权限不能更低;
重写的时候方法1申明一摸一样。
class Phone{
private void method() {
System.out.println("砸核桃");
}
public void show() {
System.out.println("show fu");
}
public void call(String name) {//String name=奥利给
System.out.println("给"+name+"打电话");
}
}
class HuaWei extends Phone{
@Override //检测是否去重写了父类的方法 可可可不写,写了最好,提示你的方法名是否写错
public void show() {
System.out.println("show zi");
}
//重新写一遍
public void call(String name) {//String name=奥利给
//调用父类的call方法
super.call(name);//奥利给
System.out.println("看视频...");
}
}
public class Demo02 {
public static void main(String[] args) {
HuaWei huaWei=new HuaWei();
huaWei.call("奥利给");
}
}