您的位置:首页 > 其它

6. 面对对象(高级) Part 1 --- 学习笔记

2014-06-16 17:17 369 查看
本章目标

掌握继承的基本概念及实现
掌握继承实现的各种限制
掌握子类对象的实例化过程
掌握方法覆写的概念及实现
掌握super关键字的作用
掌握抽象类与接口的基本概念、区别及实际应用
掌握对象多态性的作用
掌握常见的设计模式
掌握Object类的作用及其主要方法的作用
掌握包装类的作用以及自动装箱和拆箱的操作
掌握匿名内部类的使用

对于面对对象的程序而言,它的精华在于类的继承,继承可以在现有类的基础之上进行功能的扩充。通过这种方式能快速地开发出新的类,而不需要编写相同的程序代码,这也是程序代码再利用的概念。

6.1 继承的基本概念

有下面两个类Person & Student, 具体代码如下:

class Person
- name: String
- age: Int
+ getName(): String
+ setName(String name): void
+ getAge(): Int
+ setAge(Int age): void
class Student
- name: String
- age: Int
- school: String
+ getName(): String
+ setName(String name): void
+ getAge(): Int
+ setAge(Int age): void
+ getSchool(): String
+ setSchool(String school): void
class Person{

private String name;

private int age;

public String getName(){

return this.name;

}

public void setName(String name){

this.name = name;

}

public int getAge(){

return this.age;

}

public setAge(int age){

this.age = age;

}

}

class Student{

private String name;

private int age;

private String school;

public String getName(){

return this.name;

}

public void setName(String name){

this.name = name;

}

public int getAge(){

return this.age;

}

public void setAge(int age){

return this.age;

}

public String getSchool(){

return this.school;

}

public void setSchool(String school){

this.school = school;

}

}

可以发现Person类中已经存在了两个属性name和age,所以在Student类中不需要再重新声明这两个属性,这时就需要考虑是不是可以将Person类中的内容继续保留到Student类中,这就关系到了类的继承。

*******实现继承的语法如下*******

class 父类{} //定义父类

class 子类 extends 父类{} //使用extends关键字实现继承!!

按照上面的格式进行继承的操作,可以将上面的Person类和Student类声明如下:

class Person{

private String name;

private int age;

public String getName(){

return this.name;

}

public void setName(String name){

this.name = name;

}

public int getAge(){

return this.age;

}

public setAge(int age){

this.age = age;

}

}

class Student extends Person{ //Student是Person的子类

//此处任何代码都不编写

}

public class ExtDemo01{

public static void main(String args[]){

Student stu = new Student();

stu.setName("forfan06"); //此时访问的方法是父类中的,子类中并没有定义

stu.setAge(28);

System.out.println("Name: " + stu.getName() + ", Age: " + stu.getAge());

}

}

从上程序可以发现,在Student类中并没有定义任何的操作,但是通过继承的功能可以直接把父类中的操作拿到子类中使用。

当然,子类也可以定义自己的属性或方法。

如下 通过子类Student扩展父类的功能

class Person{

private String name;

private int age;

public String getName(){

return this.name;

}

public void setName(String name){

this.name = name;

}

public int getAge(){

return this.age;

}

public setAge(int age){

this.age = age;

}

}

class Student extends Person{

private String school; //新定义的属性school

public String getSchool(){

return this.school;

}

public void setSchool(String school){

this.school = school;

}

}

public class ExtDemo02{

public static void main(String args[]){

Student stu =new Student();

stu.setName("forfan06");

stu.setAge(28);

stu.setSchool("WHPU");

System.out.println("Name: " + stu.getName() + ", age: " + stu.getAge() + "School" + stu.getSchool());

}

}

以上两个类Person和Student的继承关系如下图:



********只允许多层继承,不能多重继承。即一个子类只能继承一个父类,但是不允许进行多层继承;也就是一个子类可以有一个父类,一个父类还可以有一个父类**********

如下图所示:



错误的继承代码

多重继承

class A{}

class B{}

//同时继承两个类,代码错误

class C extends A,B{}

C类同时继承了A类和B类,即C类同时继承了两个父类,这是不允许的

多层继承

class A{}

class B extends A{}

class C extends B{}

B类继承了A类,C类又继承了B类。B类是A类的子类,而C类则是A类的孙子类。

*******继承的子类有时也称为派生类*******

使用extends关键字可以实现继承的关系,但是extends关键字本身含义是“扩展”,更准确地说是一个类扩展已有类的功能。

Note:使用继承时应该注意:子类是不能直接访问父类的私有成员的,子类可以调用父类中的非私有方法,但是不能调用父类中的私有成员。子类也不能直接访问父类中的私有操作(私有方法),但是可以用其他操作来间接的调用父类的私有操作(私有方法),例如setter()和getter()

6.2 继承的进一步研究

6.2.1 子类对象的实例化过程

子类对象在实例化之前必须首先调用父类中的构造方法后再调用子类自己的构造方法。(先有父类实例,然后才能产生子类实例)

现实生活中也只能先有父母,然后才有儿子!

可以在上面的例子当中加入两个各自的构造函数,Person(), Student()来验证。

6.2.2 方法的覆写

方法的覆写就是指子类定义了与父类中同名的方法,但是在方法的覆写时必须考虑到权限,即被子类覆写的方法不能拥有比父类方法更加严格的访问权限。

访问权限的大小: private < default < public

在父类中使用public定义的方法,则子类的访问权限必须是public,否则无法编译。

子类中的同名方法的访问权限要和父类同级或者访问权限比父类大!!

如果要在子类的防范中访问父类的方法,则使用super关键字即可(在覆写了父类的方法 前提下)

*******方法覆写时从private(父类方法的访问权限)变为default(子类方法的访问权限),这样不算是方法的覆写。*******

*******此时只是在子类中重新定义了一个新的方法,父类中的该方法没有被覆写*******

6.2.2.1 属性的覆写

调用父类中的属性时,需用到super.XXX

**********方法的重载与覆写的区别**************



6.2.3 super关键字的作用

使用super关键字可以从子类中调用父类中的构造方法、普通方法和属性。

1. 使用super调用父类中指定构造方法。与this调用构造方法的要求一样,语句必须放在字类构造方法的首行。

2. this和super都可以调用构造方法,但是两者不可以同时出现,因为两者调用构造方法时都必须放在新的构造方法首行。无论子类如何操作,最终必须要先调用父类中的构造方法。

3. this与super的区别



6.2.4 范例 -- 继承的应用

定义一个整型数组类,要求包含构造方法、增加数据及输出数据成员方法,并利用数组实现动态内存分配。在此基础上定义出以下子类:

(1) 排序类: 实现排序

(2) 反转类: 实现数据反向存放

分析:要求数组实现动态的内存分配,就是说其中数组的大小由程序外部决定,则在本类的构造方法中应该为类中的数组进行初始化操作,之后每次增加数据时都应该判断数组的内容是否是满的,如果不是满的,则可向其中添加;如果是满的,则不能添加。并且每添加数据时,需要一个指向可以插入的下标,用于记录插入的位置。

实现代码如下:

class _Array{

private int temp[] = null;

private int foot = 0;

public _Array(int len){

if (len > 0){

this.temp = new int[len];

}else {

this.temp = new int[1];

}

}

public boolean add(int i){

if (this.foot < this.temp.length){

this.temp[this.foot] = i;

this.foot++;

return true;

}else {

return false;

}

}

public int[] getArray(){

return this.temp;

}

}

class SortArray extends _Array{

public SortArray(int len){

super(len);

}

public int[] getArray(){

java.util.Arrays.sort(super.getArray());

return super.getArray();

}

}

class ReverseArray extends _Array{

public ReverseArray(int len){

super(len);

}

public int[] getArray(){

int ra[] = new int[super.getArray().length];

int count = ra.length - 1;

for (int i = 0; i < ra.length ; i++){

ra[i] = super.getArray()[count];

count--;

}

return ra;

}

}

public class InheriteDemo{

public static void main(String args[]){

ReverseArray ra = null;

ra = new ReverseArray(5);

System.out.println(ra.add(5) + "\t");

System.out.println(ra.add(1) + "\t");

System.out.println(ra.add(0) + "\t");

System.out.println(ra.add(9) + "\t");

System.out.println(ra.add(4) + "\t");

System.out.println(ra.add(8) + "\t");

for (int i = 0; i < ra.getArray().length; i++){

System.out.println(ra.getArray()[i] + "\t");

}

SortArray sa = null;

sa = new SortArray(5);

System.out.println(sa.add(15) + "\t");

System.out.println(sa.add(61) + "\t");

System.out.println(sa.add(30) + "\t");

System.out.println(sa.add(98) + "\t");

System.out.println(sa.add(74) + "\t");

System.out.println(sa.add(81) + "\t");

for (int i = 0; i < sa.getArray().length; i++){

System.out.println(sa.getArray()[i] + "\t");

}

}

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: