多态是指同一个方法可以根据发送的对象不同而采用多种不同的行为方式。一个对象的实际类型是确定的,但可以指向对象的引用类型有很多,如:父类或与父类有关系的类。
例:父类的引用指向子类,如下式所示。
Person s = new Student(); s.test();
其中,Person为父类,Student为子类,上式子的引用类型为父类Person,实际上new了一个子类对象Student()。
在上述例子中,调用方法s.test()时,子类如果没有重写父类方法,就会调用父类方法,如下图所示。
如果子类有重写,就调用子类的重写方法,如下图所示。
注:
父类引用类型,可以指向子类对象,但是不能调运子类中的独有方法。如下图所示。
子类引用类型,可以指向子类对象,所调用的方法为都是自己的或者继承父类的。如下图所示。
可以使用强制类型转换,将高的父类类型转化为低的子类类型,如下图所示。
多态是方法的多态,属性没有多态。
存在子类、父类或者两个有关系的类,才能出现多态特征。
多态存在条件:继承关系、方法需重写、父类引用指向子类对象。
static、final、private修饰符所修饰的方法,都不可重写,即没有多态,如下图所示。
在引用类型中,高转低(向下转型)--->用强制转换(与在基本类型中的转换相似),如下图所示。
低转高(向上转型)--->用自动转换,如下图所示。
注:
向下转型时,可能会丢失自己本来的一些方法(类似于基本类型中的强制类型转换会丢失精度)。
引用类型的转换发生在父、子类之间,依旧遵循基本类型转换的原则,低转高用自动转换,高转低用强制转换。
补充:
instanceof 用于判断对象的类型,如下式子所示。
A instanceof B
其中:A为对象变量,B为引用类型,表达式返回值为boolean型,具体效果,如下图所示。
注:A、B两类必须有关系才能进行比较,即父子关系是否具有。
使用static修饰符,可以让多对象实例来使用,可在多线程中使用。在同一类中的其他静态、非静态方法可以直接调用此静态方法,如下图所示。
匿名代码块(又名实例代码块)在创建类时创建,在构造器之前产生。匿名代码块每创建一个对象的时候对执行一次,起到对象初始化的作用。如下图所示。
静态代码块,比匿名代码块创建早,与类同时产生,在构造器之前产生。静态代码只执行一次,在类加载时初始化。如下图所示。
注:
不同种类之间优先级别:静态代码块 > 匿名代码块 > 构造方法
同种类之间的优先级别:即类中书写的先后顺序,先写的先执行。
如下式所示
import static java.lang.Math.random
通过上述的方法,可在项目中导入Math类中的random方法,在后续类的使用中,可以直接使用random()来调用这个方法,如下图所示。
补:通过final所修饰的类,不能被继承!!!(final之后"断子绝孙")
抽象类关键字:abstract
关键字加在类前构成抽象类,它是一种约束。
关键字加在方法前构成抽象方法。抽象方法是指,只有方法名字,却没有方法实现。
抽象类的所有方法,继承了它的子类,都必须要去实现它的方法。如下图所示。
抽象类特点:
不能new出抽象类,抽象类仅仅是一种约束。
只能依靠子类去实现它,实现后,其子类才可以被实例化,否则需要依靠子子类。
抽象类里也有正常的方法,但抽象方法必须在抽象类中。
补充:抽象类本质为一个类,故它具有类默认产生的无参构造器。抽象类的存在,可以在宏观层面进行框架搭建,提高了效率。
接口就是一种规范、一种专业的约束,它定义了一组规则。接口的本质就是契约,按照契约来进行方法的编写。
接口只是一种规范,自身内部无法写正常的方法,接口中所有的定义都是抽象的。
声明接口的关键字为:interface,具体形式,如下图所示。
接口都需要一个实现类,一般来说实现类以"Impl"作为结尾。实现类的定义,关键字为:implements,如下图所示。
综上:类可以用来实现接口,接口中只有方法的定义,实现了接口的类,就必须重写接口的方法!!!
接口的出现,实现了多继承关系,单个类可以实现多个接口,在单个类中实现了多个接口中定义的方法,如下图所示。
补充:
接口起到约束作用。
接口中的方法,默认前缀:public abstract。属性,默认前缀:public static final。
接口不能实例化,接口中没有构造方法。
implements可以实现多个接口。
实现类必须实现接口中的方法。
内部类是指在一个类的内部再定义一个类。
内部类可以分为以下几种:
成员内部类,如下图所示。
内部类对象的引用,如下式子所示。
Outer outer = new Outer();//先new外部类对象 Outer.Inner inner = outer.new Inner();//后new内部类对象
使用具体效果,如下图所示。
注:使用内部类可以获得外部类的私有属性和方法。如下图所示。
静态内部类,静态内部类中无法访问非静态外部类的私有属性。因为带有static的静态内部类随着类的声明先创建。
静态内部类的创建,如下图所示。
静态内部类的声明,如下式所示。
Outer outer = new Outer();//先new外部类对象 Outer.Inner inner = new Outer.Inner();//后new内部类对象
使用具体效果,如下图所示。
匿名内部类
为了解决在实际开发过程中,一个类或接口的方法,只会在程序中执行一次,却还需要创建实现类等繁琐的代码编写的问题。通过使用匿名内部类减少了类的数量,更高效的编写程序,减少代码。
匿名内部类可以没有名字便初始化类,不用将实例对象保留在变量中。注:匿名匿的是所创建对象的存储变量,如下图所示。
也可以实现接口实现类的匿名,即:直接new出实现接口的类,创建接口实现类的对象,并匿名(匿名匿的是所创建对象的存储变量,即不用将实例对象保留在变量中),如下图所示。
匿名类、接口的使用,如下图所示。
注:一个Java程序中可以有很多的class类,但只能有一个public class 类,如下图所示。
局部内部类
局部内部类为在一个方法中定义一个类,它的作用域仅限于这个方法,如下图所示。
局部内部类的使用,如下图所示。