- 认为客观世界由各种对象组成,任何事物都是对象,复杂的对象可以由比较简单的对象以某种方式组合而成
- 把所有对象都划分成各种对象类,每个对象类都定义了一组数据和一组方法
- 按照子类与父类的关系,把若干个对象类组成一个层次结构的系统
- 对象彼此之间仅能通过传递消息互相联系
类间多态和类内多态
多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作
类间多态性
父子类之间的一种多态性 例如:动物 x=new猫()
public class Test1{
public static void main(String[] args){
Animal a1=new Cat();
A a=new A();
a.eee(a1);
}
}
class A{
public void eee(Animal animal){
animal.eat();
}
}
class Animal{
public void eat(){
System.out.println("Animal.eat()");
}
}
class Cat extends Animal{
@Override
public void eat(){
System.out.println("就是爱老鼠");
}
}
class Dog extends Animal{
@Override
public void eat(){
System.out.println("就是爱肉骨头");
}
}
- 方法调用中的限制:
针对一个类对象有两种类型,一种称之为编译期类型,编译时系统识别对象的类型,
”
动物
x = new
猫
()”
在编译时,系统识别
x
是动物类别的,所以只能调用动物类定义的方法,而不能调用猫中特殊
的方法。另外一种称之为运行时类型,也就是当程序运行系统识别的类型,
new
谁就是谁
- 覆盖的方法一定不能是private的
类内多态性
在一个类对象上调用相同名称的方法,但是当参数不同时执行不同的动作
public class Test2{
public static void main(String[] args){
A2 a=new A2();
//a.pp();
//a.pp(12);
a.pp("shitou");
}
}
class A2{
public void pp(){
System.out.println("A2.pp()");
}
public void pp(Integer k){
System.out.println("A2.pp(int)");
}
public void pp(Object kk){
System.out.println("A2.pp(String)");
}
public void pp(int k1,String k2){}
public void pp(String k1,int k2){}
}
方法名称相同,参数不同,和返回值类型无关
- 参数个数不同
- 参数类型不同
- 参数顺序不同。注意不同参数名称顺序不同
public class Test1{
public static void main(String[] args){
Fa ff=new Fa();
ff.pp(new Integer(123));//原则:最佳匹配
ff.pp(1.234);
}
}
class Fa{
public void pp(){
System.out.println("Fa.pp()");
}
public void pp(Number kk){
System.out.println("Fa.pp(Number)");
}
public void pp(Integet kk){
System.err.println("Fa.pp(Integer)");
}
}
不确定个数的参数
public class Test1{
public static void main(String[] args){
Fa ff=new Fa();
ff.pp();//最佳匹配原则
}
}
class Fa{
public void pp(){
System.out.println("Fa.pp()");
}
public void pp(int...pages){
System.out.println("Fa.pp(int...)");
}
}
方法的重写和重载
要求:方法的名称一致。
方法的重写
(
覆盖
)
要求:方法的名称一致
方法的重写
(
覆盖
)
一定发生在父子类之间
public class Test4{
public static void main(String[] args){
F4 f=new F4(); f.pp(10);
S4 s=new S4(); s.pp(10);
F4 fs=new s4(); fs.pp(10);
}
}
class F4{
public void pp(int k){
System.out.println("F4.pp(int)");
}
}
class S4 extends F4{
public void pp(int k){ //子类中定义的同名同参数的方法覆盖了父类中的定义方法
//如果需要调用父类中的方法则需要super.pp(k)进行调用
System.out.println("S4.pp(int)");
}
}
执行规则:new谁运行谁的方法,和声明的类型无关
方法的覆盖定义要求方法名称一致
@Override注解可以使IDE工具在编译源代码时进行检查,如果有手写错误则IDE工具报错
方法的参数一致(个数、类型、顺序),和参数名称无关
类型一致的问题
class Fa{
public void eat(Integet kk){
System.out.println("Animal.eat()");
}
}
class Son extends Fa{
@Override
public void eat(Number kk){
//类型必须一致,即使父类类型都不可以,int和 Integer简单类型和包装类型也不可以。这里去除@override注解则不会有语法错误,这里不是 方法的重写,是方法的重载
System.out.println("就是爱老鼠");
}
}
顺序一致的问题,系统识别方法依靠是方法名称和参数类型列表,和方法参数的名称无关。例如这里系统识别的方法为ear(String,String)。要识别顺序还得依靠类型的区别,例如eat(int,double)和 eat(double,int)
class Fa{
public void eat(String s1,String s2){
System.out.println("Animal.eat()");
}
}
class Son extends Fa{
@Override
public void eat(String s2,String s1){
System.out.println("就是爱老鼠");
}
}
返回数据类型一致
(
因为如果返回类型不一致,则无法进行语法检查
,
例如父类返回 Double,而子类返回
Integer,
调用处语法检查是按照
Double
进行检查还是按
Integer
检查?允许父类中返回的是父类型,而子类中返回子类型,例如父类中返回的是Number
类型,而子类中返回的
是
Integer)
class Fa{
public Number eat(double s1,int s2){
Sysstem.out.println("Animal.eat()");
return 10.;
}
}
class Son extends Fa{
@Override
public Integer eat(double s2,int s1){
//允许子类返回值类型是父类返回值类型的子类型
System.out.println("就是爱老鼠");
return 99;
}
}
抛出异常一致,注意实际上允许子类抛出比父类更少的异常
class Fa{
public Integer eat(double s1, int s2)throws Exception{
System.out.println("Animal.eat()");
return 10;
}
}
class Son extends Fa{
@Override
public Integet eat(double s2, int s1)throws IOException{
System.out.println("就是爱老鼠");
return 99;
}
}
要求子类中的方法范围
>=
父类中方法范围
静态方法覆盖和调用,用谁声明则调用谁的静态方法
只有静态方法覆盖定义父类中的静态,实际上系统不建议这种做法
//The method pp() of type Son must override or implement a supertype method
public class Test1{
public static void main(String[] args){
// 直接使用具体类调用静态方法没有任何问题,使用哪个类就调用的是哪个类中定义 的静态方法
// Fa.pp();Fa...pp // Son.pp();Son...pp
// 事实上静态方法也可以通过创建对象后,使用对象进行调用。声明变量的类型和具 体构建的类型一致,也不会有问题
// Fa ff=new Fa();
// ff.pp(); //如果调用静态方法,则用谁声明调用谁的方法
Fa ff=new Son();
ff.pp();//执行结果是Fa...pp
}
}
class Fa{
public static void pp(){
System.out.println("Fa...pp");
}
}
class Fa{
public static void pp(){
Sysout.out.println("Fa...pp");
}
}
class Son extends Fa{
public static void pp(){
System.out.println("Son...pp");
}
}