JavaSE基础——(8)Java面向对象之继承与方法

目录

一、代码块

二、继承

2.1继承

2.2继承的优缺点与特点

三、this与super的区别于应用

四、继承中的构造方法

五、方法的重写

5.1方法重写

5.2重写注意事项

5.3方法重写和方法重载的区别

六、final关键字


一、代码块

在java中被大括号{}括起来的代码被称为代码块。

根据位置和声明的不同,一般代码块可以分为:

  • 局部代码块:在方法中出现;限定变量生命周期,及早释放,提高内存利用率
  • 构造代码块:在类中方法外出现; 多个构造方法中相同的代码存放到一起,每次调用构造都执行该代码块,并且在构造方法前执行
  • 静态代码块:在类中方法外出现,加上static修饰,随着类的加载而加载,且只执行一次,用于类的初始化,一般用来加载驱动(静态代码块优先于主方法执行)
    • 在类中方法外出现,加上static修饰,随着
    • 在类中方法外出现,
  • 同步代码块(多线程)

下面我们通过代码来体会这几个代码块执行的顺序:

public class Main {
    public static void main(String[] args){
        {
            System.out.println("主函数");
        }

        Person p1=new Person();
        Person p2=new Person();
    }

    static{
        System.out.println("静态代码块");
    }
}

class Person{

    {
        System.out.println("构造代码块");
    }

    public Person(){
        System.out.println("构造方法");
    }
}

下面是运行的结果:

通过输出的顺序可以看出执行顺序为:

静态代码块->主函数->构造代码块->构造方法

并且静态代码块只执行一次,随着类的加载而加载,

构造代码块和构造方法随着对象的实例化加载而加载,并且构造代码块在构造方法之前运行。

二、继承

2.1继承

继承即在已有的类的基础上创建新的类,通过复用基础类的一些方法并且增加新的方法和字段,来增加重复代码的利用率。

这里我们使用一个简单的例子说明java如何使用继承关系:

public class Main {
    public static void main(String[] args){
        Employee e1=new Employee();
        System.out.println(e1.getSalary());
        Manager m1=new Manager();
        System.out.println(m1.getSalary());
    }
}

class Employee{
    private double salary;

    public Employee(){
        this.salary=5000;
    }

    public double getSalary(){
        return this.salary;
    }
}

class Manager extends Employee{
    private double Bonus;

    public Manager(){
        this.Bonus=5000;
    }

    public double getSalary(){
        return (this.Bonus+super.getSalary());
    }
}

由上述程序可知,我们定义了一个基类Employee,雇员有自己的初始工资5k,方法getSalary获得雇员的工资,

然后我们通过extends关键字继承了基类Employee定义了心累Manager,经理在初始工资的基础上多了一个奖金,奖金初始化为5k,

然后经理通过对方法getSalary的重写,获得经理的工资为初始工资+奖金。

最后输出结果如下:

可以看到通过继承雇员的类,然后对雇员的类进行拓展生成了新的类manager,

这样如果公司的初始工资发生变化,就不用对所有类的初始工资都进行更改,

只用更改基类的工资就可以了,这种方式大大的提高了代码的复用性。

需要注意的是,如果在子类中定义了与父类中已定义的同名变量,

那么在子类中如果对该变量进行访问,则以子类中的变量值为准,父类中的变量相当于被“覆盖”了。

2.2继承的优缺点与特点

继承的好处:

  • 提高了代码的复用性
  • 提高了代码的维护性
  • 让类与类之间产生了关系,是多态的前提

继承的弊端:

  • 类的耦合性增强了

在开发过程中,我们往往要求程序具有高内聚、低耦合的特点,

即类与类之间的相关性减少,让每个类之间尽量相互独立,这样就可以用尽可能少的类完成更多的事。

继承的特点:

  • Java中支持单继承,不支持多继承(C++中就支持多继承),即一个类只允许继承一个基类,不能继承多个基类
  • Java支持多层次继承,比如B继承于A,而C又继承于B,这样A就是最基本的类

三、this与super的区别于应用

this代表对象自身,可以理解为对象本身的一个引用,

super则代表父类对象,可以理解为父类对象的引用。

在使用中this既可以调用自身的变量或者方法,在自身没找到变量或方法名时,this会查找父类的变量或者方法进行调用,

而super只能调用父类的变量和方法。

四、继承中的构造方法

子类中所有的构造方法都默认会访问父类中无参构造方法,

因为子类一般会继承父类的变量,在子类中对这些变量进行访问,

所以当子类进行初始化时,会先执行父类中无参构造方法对父类的变量进行初始化。

public class Main {
    public static void main(String[] args){
        Son son =new Son();
    }
}

class Father{
    public Father(){
        System.out.println("父类构造方法");
    }
}

class Son extends Father{
    public Son(){
        System.out.println("子类构造方法");
    }
}

上述代码执行结果如下图:

可以看到在主函数中实例化Son对象后,先执行了父类的构造方法,然后执行了子类的构造方法。

这是因为在子类的构造函数中,系统会自动帮我们补上一句:

super();

其作用是访问父类的无参构造方法。

其实每一个构造方法的第一条语句默认都是super(),所有类都是继承于Object类。

既然要访问父类中的无参构造方法,

如果父类中没有无参构造方法,那么子类中必须显示调用父类的有参构造方法初始化变量:

子类构造方法(参数列表){
    super(参数列表);
    ...
}

五、方法的重写

5.1方法重写

方法的重写是当父类的方法在子类中重新实现,方法名称、参数列表、返回值类型均相同。

当子类需要父类的功能,而当前功能子类又有自己的实现特点时,那么通过方法的重写可以复用父类的其他功能,也定义了自己的内容。

比如在之前雇员与经理的例子中获取工资的方法,

雇员的获取工资方法为输出初始工资变量,而经理获取工资的方法为输出初始工资加奖金。

class Employee{
    public double getSalary(){
        return this.salary;
    }
}

class Manager extends Employee{
    public double getSalary(){
        return (this.Bonus+super.getSalary());
    }
}

这种就是方法的重写,如果还想继续使用父类中被覆盖的方法,那么使用super.方法名()也可以调用父类的方法。

5.2重写注意事项

在进行方法的重写时,有以下几点注意事项:

  • 父类中私有的方法无法被重写(因为私有方法无法被继承也就没办法被重写)
  • 子类在重写父类方法时,访问的权限不能越来越低,比如父类的方法为public时,子类重写时不能将权限改为比public低的protected或者private
  • 父类中静态的方法,子类在进行重写时也必须为静态方法
  • 子类重写父类方法时,最好声明一样

5.3方法重写和方法重载的区别

  • 方法重写:子类中出现了与父类中方法声明一模一样的方法,与返回值类型有关,返回值是一致的。
  • 方法重载:本类中出现的方法名一样,参数列表不同的方法,与返回值类型无关。

在子类对象调用方法时,其一般顺序为现在子类本身的方法中寻找,找不到则取父类继承的方法中找。

六、final关键字

final作为一个关键字,可以用来修饰类、变量和方法:

  • final修饰一个类时,该类不能被继承
  • final修饰一个变量时,变量被赋值后它的值就无法被修改
    • 当变量为基本数据类型时,其值无法被改变
    • 当变量为引用数据类型时,其地址值无法改变,但是对象中的属性可以改变
  • final修饰方法时,方法无法被重写

final修饰变量时必须要显示初始化,给一个初始值,不能不写用java默认值,

如果不给一个显示的初始化值,则必须在构造方法内对final的变量进行初始化。

猜你喜欢

转载自blog.csdn.net/weixin_39478524/article/details/109563626