昨天在一个群里面一个群友问道final 方法可不可以重载,我不假思索的说final 方法不能继承不能重载。后来晚上睡不着觉想想总觉得不对头,翻翻书一看自己简直就是胡说八道,才意识到这些基础概念的东西时间久了不深究很容易模糊变得模棱两可,尤其对于自己这种学东西不求甚解的人来说更是家常便饭。带着昨天血淋淋的教训,决定重头来过,今天这篇小笔记就算是一个开始吧!

一.重载

java的方法重载,就是在类中可以创建多个方法,它们具有相同的方法名,但具有不同的参数类型列表。java方法重载的典型应用就是java构造器的使用,方法重载也是java多态性的重要表现。

下面的例子援引《thinking in java》,同时示范了重载的构造器和重载的方法:

class Tree{
int height;
Tree(){
System.out.println("Plantinga seeding");
height = 0;
}
Tree(int initialHeight){
height = initialHeight;
System.out.println("CreatingNew Tree that is" + height + "feet tall");
}
void info(){
System.out.println("Tree is" + height + "feet tall");
}
void info(String str){
System.out.println(str+":Treeis " + height + "feet tall");
}
}
public classOverloading {
public static void main(String[] args) {
Tree tree = new Tree(5);
tree.info();
tree.info("overloadingmethod");
//Overloaded Constructor
new Tree();
}
}

上面例子的输出结果为:

Creating New Tree that is5feet tall
Tree is 5 feet tall
overloading method:Tree is 5feet tall
Planting a seeding

关于重载的方法还有如下几点说明:

1,每个重载的方法都必须有一个独一无二的参数类型列表。

2,参数顺序的不同也足以区分两个方法。如下面的代码中的两个方法也是重载的方法

static void f(String s , int i){
}
static void f(int i , String s){
}3,无论是在子类或者它的父类中对已有的方法进行定义,重载机制都可以正常工作。例如:
class Father{
void method(char c){
}
void method(float f){
}
}
class Son extends Father{
void method(double d){
}
}

4,根据方法的返回值来区分重载方法是行不通的。原因很简单,比如现在有 void f(){ }和 int f(){return 1;}两个方法,当我们在另外一个地方需要调用其中的某个方法的时候,如果我们仅仅用 f(); 来调用方法,此时java就无法判断该调用哪个f()方法了。

二.覆写

覆写也叫重写。如果在子类中定义与父类具有相同名称和参数的方法,我们就说该方法被覆写。看下面的代码:

class Father{
void method(char c){//①
}
void method(float f){//②
}
}
class Son extends Father{
void method(double d){//③
}
void method(char c){//④
}

}我们需要区分的是,方法③属于重载的方法,而方法④属于重写的方法。

关于方法的重写归纳一下几点:

1,java中子类可以继承父类的方法而不需要重写,但如果子类不想照搬继承自父类的方法而想做一定的修改,这个时候就要用到方法的重写。

2,当子类的方法覆写了继承自父类的方法时,在子类这个层次从父类继承过来的方法将被隐藏,如需调用该方法,需使用super关键字,该关键字指向当前类的父类

3,很多时候我们想要重写一个方法时,往往因为该方法的参数类型列表没有与父类中的方法完全吻合而造成对该方法进行了重载而不是我们想要的重写。这个时候我们可以使用@Override注解。例如下面的代码:

class Father{
void method(char c){//①
}
void method(float f){//②
}
}
class Son extends Father{
@Override
void method(double d){//③
}

}运行上面的代码,编译器会生成一条“method  does not override a mehtod from its superclass” 错误信息。因为我们希望方法③是个覆写方法的,而实际却写成了重载的方法。所以@Override注解可以防止你在不想重载时而意外的进行了重载。

三.final 方法

使用final方法的原因有两个。第一个原因是把方法锁定,以防止任何继承修改它的含义。这是出于设计的考虑:想要确保在继承中使方法行为保持不变,并且不会被覆盖。第二个原因是出于效率,因为在现在新版本的java中已经得到了解决,所以不再需要final方法来进行优化了。所以我们说,只有在想要明确禁止覆盖时,才将方法设置为final的。

对于final方法的讲述再看最后一个例子:

class Father{
private final void method(){//①
}
}
class Son extends Father{
private final void method(){//②
}

} 是不是会觉得上面的代码有问题?其实不然,上面的代码是合法的。并不是上面说的final 方法不能被覆写的理论是错的,而是我们要注意这里的方法其实是私有的(private),而私有的方法是不能被继承的。所以这里我们可以理解为 方法② 是在子类中定义的一个全新的方法,而非对父类方法的重写。