Java学习笔记--继承和多态(上)
1.通过继承来开发超类(superclass)
2.使用super 关键词唤起超类的构造方法
3.在超类中覆盖方法
4.区分override和overload
5.在Object类中探索toString()类
6.发现多态性和动态绑定
7.描述解释为什么向下转型是必须的
8.在Object类中探索equals 方法
9.存储,取回,实现ArrayLis的对象
10.使用ArrayList类实现Stack
11.超类中使用数据和方法,protected
12.使用final模块来禁止类和方法的覆盖
回顾:
面向对象的思想:你可以从现存的类中获得新的类,这就是继承。继承是Java中重要且功能强大的特征,可以重用软件,假设遇到如下问题:需要circles, rectangles 和 triangles 这几个类可以通过继承某个类而得到。
1.通过继承来开发超类(superclass)
父类和子类(superclass 和 subclass)
使用类来对相同问题进行建模,因为不同的类有很多相同的属性和行为,这些行为可以在一些类中生成,并且其他类也可以共享。通过继承可以定义一个公有类并且之后可以扩展到更多特殊的类,这些特殊类从共有类中继承了属性和方法。
例如 几何物体的对象,假设你想要设计类和对几何对象进行建模,例如circle 和 rectangle。几何对象有很多相同的属性和行为,比如它们可以以某种颜色画出,填充或者非填充。
例子:我们写这三个类: GeometricObject Circle
public class GeometricObject { private String color; private boolean filled; private java.util.Date dateCreate; public GeometricObject(){ ; //constructor method } public GeometricObject(String color, boolean filled){ ; //constructor method with parameters } public String getColor(){ return color; //get the color for the Geometric Object } public void setColor(String color){ this.color = color; // set the color } public boolean isFilled(){ if(filled) return true; else return false; } public void setFilled(boolean filled){ this.filled = filled; } public java.util.Date getDateCreated(){ return dateCreate; } }
Circle
public class Circle extends GeometricObject{ private double radius; public Circle(){ ; } public Circle(double radius){ this.radius = radius; } public Circle(double radius, String color, boolean filled){ this.radius = radius; this.setColor(color); this.setFilled(filled); } public double getRadius(){ return radius; } public void setRadius(double radius){ this.radius = radius; } public double getArea(){ return radius*radius*3.14; } public double getPerimeter(){ return 2*radius*3.14; } public double getDiameter(){ return 2*radius; } public void printCricle(){ System.out.println("This is a printCirlce method");; } }
GeometricObject Circle 这两个类:GeometricObject类可以用来建立所有的几何模型,这个类包含了颜色Color和填充filled,还有设置属性和得到属性的方法。在Java中关于这两个类个关系:GeoetricObject 是父类,Circle 是子类,Circle类继承了所有的数据区域并且也能够新增数据和方法
关于语法的关系,Circle和GeometricObject。下面几点需要注意:
1 子类存储有更多信息和使用更多方法
2 父类的私有数据区不能够让外部类直接访问。
3 并不是所有我们认为的 xxx 是 xxx(圆是几何图形)都可以使用继承的思想
4 继承的关系是对xxx是xxx的建模
5 一些编程语言允许将子类从父类中分离出来
2.使用super 关键词唤起超类的构造方法
子类从父类中继承数据区和方法,能否继承构造方法,或者说子类能否唤起父类的构造函数。super参考了类的父类:
1 调用父类的构造方法
2 调用父类的方法
调用父类的构造方法法,语法如下
super(); super(parameters);
super();的语句唤起了父类无参数的构造方法。
super(parameters);唤起有参数的构造方法。
注意:你使用super 关键词来唤起父类的构造函数,而且唤起必须是构造的第一步。
构造连锁:
无论在什么情况下,在子类中构造类的实例都会调用父类的构造方法,如果父类是从其他类中分离出来的,子类的构造方法一开始就要唤起父类的构造方法。
例子如下:
public class Person { public Person(){ System.out.println("(1)Performs Person's tasks"); } }
此时为构造Person类的方法
public class Employee extends Person{ public Employee(){ this("(2)Invoke Employee's overloaded constructor"); System.out.println("(3)Performs Employee's tasks "); } public Employee(String s){ System.out.println(s); } }
通过Person生成雇员类
public class Faculty extends Employee{ public static void main(String[] args) { // TODO Auto-generated method stub new Faculty(); } public Faculty() { System.out.println("(4)Performs Faculty's tasks "); // TODO Auto-generated constructor stub } }
通过雇员具体化到某个实体人,观察println输出的字符串,按照如上的代码中显示的顺序,发现第一步构造person类,然后是Employee类的唤起覆盖构造方法,最后才是构造雇员类,调用雇员的构造方法。这个程序的构造过程可以按照如下的图
Faculty调用Employee类的构造方法,Employee类调用person的构造方法,接着因为构造了Person类才能够产生Employee类,有了Employee类才能够生成Faculty类。很像数据结构中学习的栈的思想,一步步压入栈,最后调用顺序就是出栈的顺序。
注意:为了使得类的设计能够很好地进行扩展,在父类的构造方法里一般的参数设置为空防止出现语法错误,也就是说在设计很多类的时候一般要留有空的构造方法,这样才能良好地扩展。
Super关键词也可以调用其他方法而不是只调用构造方法。按照如下的语法
super.method(parameters);
3.在超类中覆盖方法
子类从父类中继承了构造方法,但是有时候子类在实现的时候要修改父类的方法才能实现,这就是方法的覆盖
1.实例的方法只有在允许访问的时候才能覆盖,所以父类的私有方法不能够覆盖,因为外部不能访问私有类,子类中的方法对于父类而言是私有的,所有父类也不能访问,这两种方法是完全无关的
2.像实例方法,静态方法可以被继承,然而静态方法不能被覆盖,静态方法在父类中被定义了,在子类中要重新定义,对于子类而言,父类的静态方法是隐藏的。隐藏的方法可以使用一下的语法来访问
SuperClassName.staticMethodName.
4.区分override和overload
override 是覆盖,overload是重载,可以根据英文单词来记忆,ride 和load,覆盖和重载,子类方法覆盖了父类中的方法。在类中可以有很多的方法命名相同,但是参数的不同,Java可以overload,就是说可以根据使用时候的参数来找到匹配的方法。
按照下面的伪代码
覆盖:
puiblic class A{ public void p(){ this is p method in the class A; } } pubic class B extends A{ public void p(){ this is a p method override from A,and we can use other statement } }
重载:
public class A{ public double p(parameterType pa){ statement ; return value; } public int p(int pa){ statement; return value; } }