深入剖析Java框架源码的设计之重载与重写、构造方法的区别详解

本文深入探讨了Java中的重载和重写概念,阐述了它们的根本区别和详细对比。重载用于在同一类中创建多个同名但参数不同的方法,而重写则在子类中实现父类方法的特定行为。构造函数是类初始化的重要部分,不能被重写,但可以被重载以提供不同参数的实例化方式。通过理解这些概念,开发者可以更好地设计和实现自定义框架,创建具有多种功能的同名方法,并通过调整参数来实现多态性。文章还提供了Jedis库的源码示例,展示了如何利用重载和重写来构建灵活的API。

前言

提到重载与重写,大家最熟悉的地方莫过于自己封装一个枚举类或者框架中的底层实现类吧?我们经常用着底层的框架技术,但是底层的原理可能不太明白。下面我就来通过Java类的三大特性——封装、继承、多态的具体实现:重载与重写来深入剖析Java的设计原理,让大家可以简简单单写底层源码!

根本区别

根本区别: 重载是一个父类方法多个不用的子类功能,重写是一个父类方法多个相同的子类功能.
相当于重载是在创造方法,重写是给子类使用方法!
构造函数是为了在类加载时初始化多个变量的值,也可以在new对象时初始化值!

详细对比

1、使用static修饰的方法只能执行一次,不能再次被实例化; 2、构造函数是一种特殊的方法,方法名与类名相同,构造函数是重载的一种实现,构造函数不能被重写(因为构造函数是一个无自己方法的类型-采用this全局引用符引用的本类中的参数、无自己的返回值-返回值是本类参数的、类名与参数名相同,这三点也就导致构造函数不满足重写的条件——必须修改父类的参数的值,没有返回值就无法修改值,因此子类无法继承父类的方法——总之重载的方法无法被重写,因此已经回不到父类的默认方法了——再底层一点就是:重载是创建一个新的同名方法来扩容原方法参数与功能,从本质上调用的是一个新方法;而重写是在原方法的基础上改变参数的值来实现原功能,从本质上还是调用的原方法) 3、重载与重写是指对方法操作,方法名都相同,参数的值都可以不同; 4、重载是改造原方法的功能(一个类中,参数类型、个数、顺序不相同),重写是重现原方法的功能(子类中,参数类型、个数都相同,但参数的值必须不同) 5、重载用于构造函数,同一个方法名对不同参数的功能实现(即实现一个方法多个功能),重写用于继承父类并再度封装父类的方法
6、在一个类中,可以有多个构造方法(方法参数不同) ,即默认重载方法,来实现对象属性不同的初始化;
7、但是子类中不能定义一个方法无void无返回值的方法,编译错误,即子类无法继承构造方法,但是子类的构造器中可以调用(实例化)父类的构造方法(默认自动调用无参构造);然后,一个父类方法被重载为了构造函数,然后再重写为子类方法,那么构造函数该岂不是指向两个相同的地址?根据JVM的分区,用户方法与对象(非JDK对象)都会放入堆,而堆中的指针是唯一的——相当于内存区的计数器。所以是不能在(重载过的)构造方法上重写的!
8、this是用于指向的当前类(对象)的指针,可以通过this.变量名在构造函数中调用变量的值
9、this() 不能使用在普通方法中,只能写在构造方法(类名与方法名相同,无返回值)中:

public class Student { //定义一个类,类的名字为student。 
 public Student() { //定义一个方法,名字与类相同故为构造方法
  this(“Hello!”);
 }
 public Student(String name) { //定义一个带形式参数的构造方法
 }
}

10、一个实体类再创建后会自动生成一个默认构造函数,是无返回参数的,只有指向实体类的变量指针(this);同时,构造函数可以自定义(即初始化时加入一些不同的元素)
11、Java核心是对象(万物即可对象,对象即类),而类(对象)的核心就是封装、继承、多态,具体体现是重载、重写与构造函数。
12、this关键字只能访问本类中的成员变量,同时:

this调用本类中的属性,也就是类中的成员变量;
this调用本类中的其他方法;
this调用本类中的其他构造方法,调用时要放在构造方法的首行。

拓展

既然我们已经深入了重载与重写的区别、构造方法的底层,那么,我们就可以去利用这三样东西去创建属于自己的框架源码了。首先,可以重载大量的方法形成不同功能的同名方法(也就是构造方法),然后根据方法体的参数的不同就可以调用不同的功能(参数的值可以自己设置),这就实现了一个方法的多个功能的封装(根据参数不同来选择)。比如:使用Jedis调用方法:
源码:

public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommands, AdvancedJedisCommands, ScriptingCommands, BasicCommands, ClusterCommands, SentinelCommands, ModuleCommands {
    protected JedisPoolAbstract dataSource = null;
​
    public Jedis() {
    }
​
    public Jedis(String host) {
        super(host);
    }
​
    public Jedis(HostAndPort hp) {
        super(hp);
    }
​
    public Jedis(String host, int port) {
        super(host, port);
    }
​
    public Jedis(String host, int port, boolean ssl) {
        super(host, port, ssl);
    }

上面是Jedis使用构造函数封装方法的源码,我们可以借鉴上面的源码自己封装底层API(可以是对其他数据库的操作)或者自己封装属于自己功能的方法;当封装的方法足以完成一个完整的操作的时候,我们就可以将其打成Jar包发布到Maven Center,从而形成一个框架。Jar包多了,这时候可以下载OpenJDK的某一个版本,然后将自己的Jar整合到JDK中;这样,就开发出来了属于自己定制功能的JDK版本。npm同理~

// 对overload测试的文件:OverloadTest.java public class OverloadTest { // 下面几个方法用来验证可以通过定义不同的参数类型参数的数目进行方法重载。 public void fun(){ System.out.println("method fun in OverloadTest, no parameter"); } public void fun(float f) { System.out.println("method fun in OverloadTest, parameter type: float"); } public void fun(int i){ System.out.println("method fun in OverloadTest, parameter type: int"); } public void fun(int i1, int i2) { System.out.println("method fun in OverloadTest, parameter type: int, int"); } // 下面的两个方法用来验证可以通过定义不同的参数顺序进行方法重载。 // 需要注意:这里的参数肯定不是相同的类型,否则的顺序的先后就毫无意义。 public void fun1(int i, float f) { System.out.println("method fun1 in OverloadTest, sequence of parameters is: int, float"); } public void fun1(float f, int i) { System.out.println("method fun1 in OverloadTest, sequence of parameters is: float, int"); } // 下面的两个方法用来验证方法抛出的异常对于重载的影响. // 无论是异常的类型还是异常的个数都不会对重载造成任何的影响。 public void fun2() throws TestException { System.out.println("fun2 in OverloadTest, exception: TestException"); } public void fun2(int i) throws TestException, TestException1 { System.out.println("fun2 in OverloadTest, exception: TestException, TestException1"); } public void fun2(float f) throws Exception { System.out.println("fun2 in OverloadTest, exception: Exception"); } // 不能通过抛出的异常类型来重载fun方法。 //public void fun(int i) throws Exception { // System.out.println("method fun in OverloadTest, parameter type: int, exception: Exception"); //} // ? 不能通过返回值重载fun方法。 //public boolean fun(int i) throws Exception { // System.out.println("method fun in OverloadTest, parameter type: int, exception: Exception, return: boolean"); // return true; //} private void fun3() { } // 不能通过不同的访问权限进行重载 public void fun3() { } public static void main(String[] args) { // 这里只是定义了OverloadTest的实例,所以test不会调用 // OverloadTest1中的方法。 OverloadTest test = new OverloadTest1(); // 这里定义了OverloadTest1的实例,因为OverloadTest1是OverloadTest // 的子类,所以test1会调用OverloadTest中的方法。 OverloadTest1 test1 = new OverloadTest1(); try { int i = 1, j = 2, m = 3; // 这里不会调用OverloadTest1的fun方法 // test.fun(i, m, j); test1.fun(i, j, m); test1.fun(); // 这个调用不会执行,因为fun3()在OverloadTest中访问权限是priavte //test1.fun3(); test1.fun3(i); } catch(Exception e) { } } } class OverloadTest1 extends OverloadTest{ // 在子类中重载fun public void fun(int i, int m, int n) { System.out.println("Overload fun1 in OverloadTest1, parameter type: int, int, int"); } // 这个不是对父类中方法重载,只是一个新的方法。 public void fun3(int i) { System.out.println("fun2 in OverloadTest1"); } } // 对override测试的文件:OverrideTest.java public class OverrideTest { public void fun() throws TestException { System.out.println("method fun in OverrideTest"); } private void fun1() { System.out.println("method fun1 in OverrideTest"); } public static void main(String[] args) { OverrideTest test = new OverrideTest1(); try { test.fun(); test.fun1(); } catch(Exception e) { } } } class OverrideTest1 extends OverrideTest{ // 以下正常Override public void fun() throws TestException2 { System.out.println("fun in OverrideTest1"); } // 不能Override父类中的方法,因为它定义了不同的异常类型 // 返回值。 //public int fun() throws TestException1 { // System.out.println("method fun in Test"); // return 1; //} // 不能Override父类中的方法,因为它抛出了比父类中非法范围 // 更大的异常。 //public void fun() throws Exception { // System.out.println("fun in OverrideTest1"); //} // 这个方法并没有Override父类中的fun1方法,因为这个方法在 // 父类是private类型,所以这里只是相当于定义了一个新方法。 public void fun1() { System.out.println("method fun1 in Test"); } } class TestException extends Exception{ public TestException(String msg) { super(msg); } } class TestException1 extends TestException { public TestException1(String msg) { super(msg); } } class TestException2 extends TestException { public TestException2(String msg) { super(msg); } }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值