您的位置:首页 > 职场人生

黑马程序员------毕老师视频笔记第七天------面向对象(继承)

2014-05-17 20:23 316 查看
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

一.继承概述

class Person
{
String name;
int age;
}
class Student extends Person
{
void study()
{
System.out.println("good study!");
}
}
class Worker extends Person
{
void work()
{
System.out.println("I'm working~");
}
}


将对象的共性的属性抽取出来,就得到了类,将几个类中的共性内容抽取出来,得到了父类。

继承:

①提高了代码的复用性

②继承让类与类之间产生了关系,有了这个关系才有了多态的特性

注意:千万不要为了获取其他类的功能,简化代码而继承,必须是类与类之间有所属关系才可以继承,所属关系 is a .谁是谁中的一员。

在java中,只支持单继承,不支持多继承(不严谨)。

多继承容易带来安全隐患,当多个父类中定义了相同的功能,当功能内容不同的时候,子类继承过来之后调用该名称的方法时不知道调用哪个。

优化了c++,c++支持多继承

但是java保留了这种机制,并用另一种体现形式来完成表示,叫做:多实现。

所以准确的说,java只是改良了多继承。

java支持多重继承,也就是一个继承体系

如何使用一个继承体系中的功能呢?

想要使用体系,先查阅体系中父类的描述,因为父类中定义的是体系中的共性功能,通过了解共性功能,就可以了解该体系的基本功能,那么这个体系已经可以基本使用了。

那么在具体调用时,要创建最子类的对象,为什么呢?

①有可能父类不能创建对象,如抽象类

②创建子类对象可以使用更多的功能,有共性的,也有特有的。

简单一句话就是,查阅父类功能,创建子类功能使用对象。

二.子父类中变量的特点

class Fu
{
int num = 4;
}
class Zi extends Fu
{
int num = 5;
void show ()
{
System.out.println(num+"..."+this.num+"..."+super.num);
}
}
class ExtendsDemo
{
public static void main (String [] args)
{
Zi z = new Zi();
z.show();
}
}



*子类父类中变量名相同的变量,直接使用的是子类的变量,因为省略了this(本类对象的引用),要想使用父类中相同名称的变量,要用super (父类对象的引用)。

super的使用和this 基本一样。

有了继承关系以后,对象在内存中的加载会出现一些变化,new Zi语句执行的时候,会在内存中开辟两片空间,先加载父类变量,后加载子类变量。super是父类的引用,this是子类的引用,但是,上面的例子中,如果子类中没有num变量会怎么样呢?

class Fu
{
int num = 4;
}
class Zi extends Fu
{
//int num = 5;
void show ()
{
System.out.println(num+"..."+this.num+"..."+super.num);
}
}
class ExtendsDemo
{
public static void main (String [] args)
{
Zi z = new Zi();
z.show();
}
}



子类中没有num,num前省略的是super,super.num是4好理解,可是怎么理解this.num也是4呢?

理解一:Zi继承了Fu之后,Zi中就有了一个num=4,所以this.num的值就是4

理解二:父类的引用指向了子类的对象,这里只有一个对象,new Zi(),this和super指向的其实都是这个对象

三.子父类中函数的特点---覆盖

如果子父类中的方法名一致会怎么样呢?

class Fu
{
void show()
{
System.out.println("Fu run");
}
}
class Zi extends Fu
{
void show ()
{
System.out.println("Zi run");
}
}
class ExtendsDemo
{
public static void main (String [] args)
{
Zi z = new Zi();
z.show();
}
}




当子类出现和父类一模一样的函数的时候,当子类对象调用该函数,会运行子类的内容,如同父类的函数被覆盖一样

这种情况是函数的另外一种特性:重写(覆盖)

当子类继承父类,沿袭了父类的功能到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新功能,而是使用覆盖特性。保留父类功能定义,重写子类功能。

提高了程序的扩展性,不用修改以前的源码。

注意:

①子类覆盖父类,必须保证子类权限大于等于父类权限,否则编译失败。

②静态只能覆盖静态

重载:只看同名函数的参数列表

重写:子父类方法要一模一样

四.子父类中构造函数的特点---子类实例化过程

class Fu
{
static
{
System.out.println("Fu class in~");
}
{
System.out.println("Fu 构造代码块 run~");
}
Fu()
{
System.out.println("Fu 构造函数 run~");
}
}
class Zi extends Fu
{
static
{
System.out.println("Zi class in~");
}
{
System.out.println("Zi 构造代码块 run~");
}
Zi()
{
System.out.println("Zi 构造函数 run~");
}
}
class ExtendsDemo
{
public static void main (String [] args)
{
new Zi();
}
}




在子类对象进行初始化时,父类的构造函数也会运行

那是因为子类构造函数默认第一行有一条隐式语句 super();

它会访问父类中空参数的构造函数,而且子类中所有构造函数第一行默认都是super();

为什么子类一定要访问父类中的构造函数?

因为父类中的数据子类可以直接获取,所以子类在建立对象时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象进行初始化时,需要先访问一下父类中的构造函数。

如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

注意:super(); 语句一定定义在子类构造函数的第一行。

因为this() 语句也只能放在构造函数的第一行,所以这两个语句只能有一个。

子类的所有构造函数,默认都会访问父类中空参数的构造函数,因为每一个子类的构造函数内的第一行都有一个隐式的super(); 当父类中没有空参数的构造函数时,子类必须手动通过super语句形式指定要访问的父类中的构造函数。当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。

子类中至少有一个构造函数会访问父类中的构造函数。

父类中的构造函数第一行也有一个隐式的super();

java中有一个类是所有类的父类------object类

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐