java重载和重写及类的加载顺序
Posted Heavy sea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java重载和重写及类的加载顺序相关的知识,希望对你有一定的参考价值。
一、方法重载(Overload)
重载概念:同一个类中,同名不同参的方法称为重载方法
多数程序语言要求为每个方法(函数)提供一个独一无二的方法名,不存在方法重载的概念。
在java中,规定方法签名是解析方法的规则而不是方法名,为方法重载开创了条件。
方法重载使得在一个类中,方法名相同而参数列表不同的方法可同时存在,代表相似的行为或功能
注意:仅有返回值不同的方法不能称为重载
public class Overloading {
public int test(){
System.out.println("test1");
return 1;
}
public void test(int a){
System.out.println("test2");
}
//以下两个参数类型顺序不同
public String test(int a,String s){
System.out.println("test3");
return "returntest3";
}
public String test(String s,int a){
System.out.println("test4");
return "returntest4";
}
}
二、方法重写(Override)
方法重写是指子类可以根据需要对从父类继承来的方法进行改写,是多态机制的前奏。
注意点:
- 重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值
- 重写方法不能比被重写方法有更严格的访问权限
- 父类中的私有方法 不能被重写
- 在子类重写的方法中继续调用父类被重写的方法可以通过 super. 函数名获取
class Person
{
String name;
int score;
public void eat()
{
System.out.println("人吃饭!");
}
public void drink()
{
System.out.println("人喝水!");
}
public void printData()
{
System.out.println("name="+name + " score="+score);
}
}
class Student extends Person
{
// 方法重写
@Override
public void printData()
{
super.printData(); // 使用父类的方法
System.out.println("子类打印!");
System.out.println("name="+name);
}
}
public class Demo {
public static void main(String[] args) {
Student s = new Student();
s.name = "haha";
s.score = 14;
s.printData();
}
}
三、类的加载顺序
对于一个类,类有静态属性、静态代码块、构造方法…那么值得思考的是这些类中的成员在初始化时的顺序是怎样的?
先给出结论:
类中各成员初始化的顺序是:
父类的静态字段——>父类静态代码块——>子类静态字段——>子类静态代码块——>
父类成员变量(非静态字段)——>父类非静态代码块——>父类构造器——>子类成员变量——>子类非静态代码块——>子类构造器
接下来用代码验证:
Father.java
package com.heavysea.l;
/**
* @author heavysea
* @date 2021/6/20
*/
public class Father {
private String hobby = "喝酒";
private static String NAME = "隔壁老王";
static {
System.out.println("父亲的静态属性:"+Father.NAME);
System.out.println("父亲的静态代码块!");
}
{
System.out.println("父亲成员变量:"+hobby);
System.out.println("父类非静态代码块");
}
public Father(String hobby) {
System.out.println("父类的构造方法");
this.hobby = hobby;
}
public String getHobby() {
return hobby;
}
public void smoke()
{
System.out.println("父亲来根华子");
}
}
Son.java
package com.heavysea.l;
/**
* @author heavysea
* @date 2021/6/20
*/
public class Son extends Father {
private String hobby = "游戏";
private static String NAME = "老王的孩子";
static {
System.out.println("孩子的静态属性:"+Son.NAME);
System.out.println("孩子的静态代码块!");
}
{
System.out.println("儿子成员变量:"+hobby);
System.out.println("孩子非静态代码块");
}
// 方法重写
public Son(String hobby) {
// 调用父类构造方法
super(hobby);
System.out.println("子类的构造方法");
}
@Override
public void smoke()
{
System.out.println("儿子表示华子来不了,来根黄山!");
}
public void swim()
{
// 调用父类的方法
super.smoke();
System.out.println("儿子去游泳");
}
}
Test.java
package com.heavysea.l;
/**
* @author heavysea
* @date 2021/6/20
*/
public class Test {
public static void main(String[] args) {
Son son = new Son("打游戏");
son.smoke();
son.swim();
System.out.println(son.getHobby());
}
}
运行结果:
运行结果非常nice,足以看出结论中类中成员的初始化顺序是正确的
四、继承中有关构造方法的问题
我们知道在子类继承父类时,如果 子类构造方法中未显式指定父类构造方法,那么将会默认执行父类的无参构造。 当然此时父类中同时实现有参构造和无参构造,子类仍然会默认执行父类的无参构造,即便仍未在子类当中指定父类构造方法。
例如:
Father.java
public class Father {
private String hobby ;
// 默认调用无参构造
public Father(){
System.out.println("父类的无参构造");
}
public Father(String hobby) {
System.out.println("父类的构造方法");
this.hobby = hobby;
}
}
此时一切正常。但如果我们重载了一个父类的有参构造而没有指定无参构造,把上面的代码注释掉,程序会报错!!!
这时候就需要在子类当中指定父类构造方法了。
Father.java
public class Father {
private String hobby ;
// 默认调用无参构造
// public Father(){
// System.out.println("父类的无参构造");
// }
public Father(String hobby) {
System.out.println("父类的构造方法");
this.hobby = hobby;
}
}
Son.java
public class Son extends Father {
private String hobby;
public Son(String hobby) {
// 调用父类构造方法
super(hobby);
System.out.println("子类的构造方法");
}
}
以上是关于java重载和重写及类的加载顺序的主要内容,如果未能解决你的问题,请参考以下文章