重载/重写/多态性
- 1.Java的重载机制
- 1.1重载定义
- 1.2重载规则
- 2.Java的重写机制
- 2.1重写定义
- 2.2重写规则
- 3.Java的多态性
- 3.1多态性定义
- 3.2多态性使用前提
- 3.3 多态性使用
- 3.4重载与多态性区别
1.Java的重载机制
1.1重载定义
- 方法名相同,参数类型、个数、顺序不同的方法 (返回类型不同不属于重载定义)
void show(int a,char c,double b) (1)
下列声明与是否(1)构成重载
void show(int a,char c,double b){} // No
void show(int a,double b,char c){} // Yes
int show(int a,double b,char c){} // Yes
int show(int a,,char c,double b){} // No
boolean show(int a,char c){} // Yes
void show(double b){} // Yes
1.2重载规则
(1)同一个类中重载: 方法必须具有不同的参数列表。
(2)子类和父类中重载:子类由于继承拥有了父类的方法,此时在子类再重载父类的方法 必须具有不同的参数列表
class Car
{
public void distance()
{
System.out.println("car can move");
}
}
class Benz extends Car
{
public void distance(int length)
{
System.out.println("Benz can move "+length+" Km");
}
public static void main(String []args)
{
Benz Maybach =new Benz();
Maybach.distance();
Maybach.distance(100);
}
}
//输出
car can move
Benz can move 100 Km
2.Java的重写机制
2.1重写定义
子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
class Animal
{
void eat()
{
System.out.print("animal eat");
}
}
class Tiger extends Animal
{
void eat()
{
System.out.print("Tiger eat");
}
}
2.2重写规则
(1) 重写方法和被重写方法具有相同的参数列表和方法名
(2) 重写方法返回类型必须和被重写方法的返回类型相同或者是返回类型的子类型。
(3) 只有实例方法才能被重写,超类中的final方法不能被重写。
(4) 重写方法不能抛出新的检查异常,或者是抛出比被重写方法声明的检查异常更广泛的检查异常。
(5) 重写方法的访问控制修饰符权限大于等于被重写方法(例如父类为缺省,子类只能为public或缺省)。
(6) 父类申明为static 的方法不能被子类重写
特殊:子类不能重写父类中声明为private权限的方法
public class Person
{
public void walk()
{
System.out.println("走路");
eat();
}
private void eat()//eat方法权限为private
{
System.out.println("吃饭");
}
}
public class Student extends Person
{
public void eat()//不是重写 即不会覆盖父类eat方法,是单独的新方法
{
System.out.println("膳食均衡");
}
public static void main(String[] args)
{
Student s1=new Student(20,"Tom");
s1.walk();
}
}
//输出情况
走路
吃饭
3.Java的多态性
3.1多态性定义
父类的引用指向子类的对象(或子类的对象赋给父类的引用)
//Animal 是父类 Dog是子类
Animal animal=new Dog();
3.2多态性使用前提
- 有类的继承关系
- 有方法的重写
3.3 多态性使用
- 虚拟方法:子类中定义了与父类同名同参数的方法,在多态情况下将此时父类方法称为虚拟方法
- 编译期只能调用父类中声明的方法。运行期实际执行的是子类重写父类的方法。
总结:编译看左边 ,运行看右边。
class Animal
{
public void shout()
{
System.out.println("Animal is shouting ");
}
}
class Dog extends Animal
{
public void shout()
{
System.out.println("汪 汪 汪");
}
public void sleep()
{
System.out.println("Dog can sleep ");
}
}
public static void main(String [] args)
{
Animal animal=new Dog();
animal.shout();// 汪 汪 汪
animalD.sleep();//此句会报错,因为编译期必须调用的父类声明的方法才能通过编译而后才能运行
}
注意:对象的多态性只适用于方法,不适用于属性(编译和运行都看左边)
// Dog类继承于Animal类 name是Dog类的属性而Animal类中没有此属性
Animal animal=new Dog()
animal.name="糯米"//错误
属性是在编译期确定的,编译时animal为Animal类型,没有name属性,因而编译错误。
3.4重载与多态性区别
重载是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了
所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;
多态只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。
class Animal
{
public void shout()
{
System.out.println("Animal is shouting ");
}
}
class Dog extends Animal
{
public void shout()
{
System.out.println("汪 汪 汪");
}
}
class Cat extends Animal
{
public void shout()
{
System.out.println("喵 喵 喵");
}
}
public static void WhoShout(Animal animal)
{
animal.shout();
}
public static void main(String [] args)
{
Animal animalD =new Dog();
WhoShout(animalD);//汪 汪 汪
Animal animalC =new Cat();
WhoShout(animalC);//喵 喵 喵
}