Java学习历程八《面向对象之继承》

Java的继承

场景:

Cat:
    name
    age
    species
    eat()
    getName()
    getAge()
    getSpecies()
    
Dog:
    name
    age
    species
    eat()
    getName()
    getAge()
    getSpecies()
    
将上述的两个类继续抽象:

Animal:
    name
    age
    species
    eat()
    getName()
    getAge()
    getSpecies()

当有Pig,Fish…类的时候,可以直接继承Animal这样极大提高代码的复用性

注意:子类不能选择性的继承父类,将继承父类所有开放的特性

继承的实现

class Animal{
    
}
class Dog extends Animal{
    
}
class Cat extends Animal{
    
}

使用extends 关键字表明前者继承后者,在Java中,继承只是单继承

父类方法的重写

方法的重载和方法重写的对比

方法重载:

  • 同一个类中
  • 同一方法名,不同参数(顺序,个数,类型)
  • 方法返回值,访问修饰符任意
  • 与方法的参数名,无关(前提其他的一致,只有参数名不同)

方法重写:

  • 有继承关系的子类中
  • 返回值类型和父类一致[可以不同]
  • 参数列表和父类一致
  • 方法名和父类一致
  • 允许访问修饰符有变化<一定范围内允许 子类的访问范围要>=父类的访问范围>
  • 允许参数名改变

子类中可以定义和父类同名的属性

上述的:

  • 返回值类型和父类一致[可以不同,允许子类]

可以不同例如:

父类:

public class Animal{
    public Animal(){}
    public Animal create(){
        return new Animal();
    }
}

子类:

public class Dog extends Animal{
    
    // 认可这种方式的方法重写返回值类型不同
    @Override
    public Dog created(){
        return new Dog();
    }
}

访问修饰符的解释

  • private 只能在当前类中访问,子类,跨包import后都无法被访问
  • public 可在任意位置访问
  • protected 受保护,当前类中可以被访问,同包子类中可访问,非同包中的子类也可以访问,无继承关系的跨包对象无法访问,同包无继承关系的实例对象可访问
  • 无修饰 默认,当前类中访问,跨包子类无法访问,同包子类可访问,跨包无继承关系的实例对象不可访问,同包下无继承关系的实例对象可访问
访问修饰符本类同包子类其他
privatev
默认vv
protectedvvv
publicvvvv

super的使用

import com.immoc.inherit.Animal;
class Dog extends Animal{
    
    @Override
    public void eat(){
        System.out.println("dog eat");
    }
    public void sleep(){
        eat();//调用dog的eat()
        super.eat();//调用父类的eat()
        System.out.println("dog sleep");
    }
}

super 还可以访问父类的属性super.name访问父类开发的name

注意:父类的构造方法,不可以被子类继承和重写

父类的构造方法的存在价值在于:

父类Animal子类Dog,当实例化Dog->one的时候,程序会先加载Animal类(定义当中的静态属性和执行静态代码块逻辑),然后加载Dog类(定义当中的静态属性和执行
静态代码块中的逻辑),然后执行父类Animal的无参构造方法,然后调用Java的内部Object类<每一个类都是Object的子类>,按照继承关系找到根类,然后一层一层的
实例化,执行父类Animal的构造代码块逻辑,构造方法,最后子类Dog构造代码块逻辑,构造方法,最终实例化出one对象

[父类静态]->[子类静态]->[父类构造]->[子类构造]

同一个类中静态属性和静态代码块的顺序,按照定义的顺序来的,代码块定义在前的先执行代码块,属性定义在前的先初始化属性

上述中,子类实例化的时候,Java会先调用父类的构造方法,如果父类有好多构造方法,子类如何选择使用哪个构造方法??

在一般情况下,自动执行父类的无参构造(所以父类要显式定义无参构造),当我们在子类的构造方法中显式super()可以显式选择父类
的构造方法,例如选择双参构造,只需要在super(arg_1,arg_2)传入相应参数即可

注意:this super 都不可以在静态方法中调用,在构造方法中使用this()代表当调用当前构造方法的时候会先调用当前类的无参构造方法,再按照
顺序执行当前构造方法块中的其他逻辑.在同一个构造方法内,this()super()只能使用其中的一个,而且需要被放在当前方法的第一位置.

Java中的Object类

Object类是Java中所有类的父类

一个类如果没有使用extends关键字明确表示父类,那么默认继承Object类

Java中每一个类都可以使用Object类定义的方法

  • equals()方法默认是用来比较两个对象的储存空间是否一致,常被重写来实现自己的比较逻辑
  • toString()方法,默认输出类型信息+@+getName()+hash直接print对象的时候会默认调用,也常常被重写

final关键字:

  • 当某个类不希望可以被继承的时候 可以在定义class的时候在class关键字之前添加final关键字来禁止生成子类{final和public关键字的顺序不限制}.
  • 同样的,如果用final修饰类的方法,那么这个方法将不能被子类重写.
  • final修饰局部变量,在定义的时候不赋值,使用的时候赋值,而且只允许被赋值一次.
  • final修饰成员属性后,不能被再次修改赋值,如果在定义的时候没有赋值,那么只能在类的构造方法,构造代码块中允许赋值<一次>

变量分为基础数据类型,引用数据类型

  • 基础数据类型经过final修饰后只能赋值一次后便不能再被赋值修改
  • 引用数据类型经过final修饰后,当形成应用后,这个引用便不能被更改,但是引用对象的属性是可以被修改的
final Animal one = new Animal();
one = new Animal(); //这样不允许
one.setName("张三");//这样允许

如果某些属性需要只能被赋值一次,且一但完成第一次赋值之后不能再被修改,那么需要使用final 和 static两个修饰符修饰

例如一些配置信息,

public static final int MAX_VALUE = 100;

注意:final修饰的方法或者属性,虽然不能被重写,修改,但是可以被继承复用,final是不允许来修饰构造方法的

Java中的注解

重写方法时候@Override就是Java中的一种注解

  • 可以声明在包,类,属性,方法,局部变量,方法参数等的前面,用来对这些元素进行说明,注释,标记

注解按照运行机制分为:

  1. 源码注解
  2. 编译注解
  3. 运行注解

@Override就是一种编译注解,标识下方方法是对父类方法重写的,如果方法不符合重写规格,那么就会报错

按来源分:

  1. 官方注解
  2. 第三方注解
  3. 自定义注解
  4. 元注解{对注解进行注解}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值