面对对象有三大基本特性:继承,封装和多态。
多态是面对对象中技术最灵活的机制,它不但可以增加程序的可维护性,还可以提高代码的可读性,多态是依赖继承性的,甚至可以说是多态性是继承性的扩展。多态性分为对象方法的多态和对象类型的多态。
- 对象方法的多态:方法的重载和重写(重载只要函数名一致即可,重写需要与父类保持一致)
对象类型的多态:在Java中,对象类型的多态可以分为向上转型和向下转型。向上转型是程序自动完成的,而向下转型必须明确指出要转型的子类型,这似乎强制的。
向上转型(将子类类型转换为父类类型)
The code:
class Person{
public void tell(){
System.out.print("父类person的tell()");
}
}
class Student extends Person{
public void tell(){
System.out.print("子类Student的tell()");
}
public void print(){
System.out.print("子类Stdudent的print方法");
}
}
public class test{
public static void main(String []args){
Person per=new Student();
per.tell();
}
}
运行结果为:”子类Student的tell方法“。
向上转型是自动的,Person per = new Student() 将子类Student创建的对象向上转型为父类Person类型,它能够调用子类Student重写父类的tell方法,但是无法调用子类Student的print方法。因为子类的实例已经转型为父类了。(向上转型是自动的,转型后的实例可以调用子类中重写父类的方法,但是无法调用子类中没有重写的方法)
- 向下转型(父类转型为子类)
The code:
class Person1{
public void tell(){
System.out.println("父类Person的tell方法");
}
public void say(){
System.out.println("父类Person的say方法");
}
}
class Student1 extends Person1{
public void tell(){
System.out.println("子类Student的tell方法");
}
public void print(){
System.out.println("子类Student的print方法");
}
}
public class test1 {
public static void main(String ages[]){
Person1 per=new Student1();
Student1 stu=(Student1)per;
stu.tell();
stu.print();
stu.say();
}
}
运行结果:
”子类Student的tell方法
子类Student的print方法
父类Person的say方法“
向下转型不是自发的,也就是说如果Student stu = new Person() 是会报错的。在进行对象的向下转型之前,必须先发生对象的向上转型,否则会报错。即,Person per = new Student()创建子类Student的实例并且赋值给父类Person引用,在Student stu = (Student)per中强制将per转换为子类对象stu实现向下转型。
只需要记住,最后相关联的一定都是要以实例化后的实例为标准,那才是真实存在的东西,其他的都只是简单的引用罢了
特例:
- 子类重写父类的静态方法和子类重写父类的实例方法
class Person2{
int i1=1;
static int i2=10;
public void tell(){
System.out.println("父类person的实例方法tell");
}
public static void staticTell(){
System.out.println("父类person的静态方法staticTell");
}
}
class Student2 extends Person2{
int i1=2;
static int i2=20;
public void tell(){
System.out.println("子类Student的实例方法tell");
}
public static void staticTell(){
System.out.println("子类Student的静态方法staticTell");
}
}
public class test2 {
public static void main(String []args){
Person2 per=new Student2();
System.out.println("i1="+per.i1+",i2="+per.i2);
per.tell();
per.staticTell();
Student2 stu=(Student2)per;
System.out.println("i1="+stu.i1+",i2="+stu.i2);
stu.tell();
stu.staticTell();
}
}
运行结果:
分析:根据向上转型的规则,转型为父类的实例原则上应该是调用子类重写的父类方法的,但是上图中的红线箭头处调用的却是父类的方法。敲黑板了!
注意:
在运行时Java虚拟机把静态方法和所属的类绑定,而把实例方法和所属的实例绑定,成员变量(包括静态变量和实例变量)与所属的类绑定。
所以,上述的Java向上向下转型都需要遵循Java虚拟机的绑定规则。
封装类的继承关系
Character和Boolean类属于Object类的子类
Byte、Short、Integer、Long、Float和Double均属于Number类的子类
封装类属于引用数据类型,具有属性和方法,使用这些方法可以实现很多基本数据类型所没有的功能。封装类主要提供以下两个功能:
1、将基本数据类型封装后,可当作对象进行使用。
2、为基本数据类型提供各种转换功能,如将数值转换为字符串、将字符串转换为数值等。
小结:
Java是一门充满神奇的语言,但是核心与 C语言依赖于内存一样,它的JVM才是最终的大BOSS,重点需要攻克JVM,当然现在的首要任务就是完成语言关。