-------------------------ASP.Net+Unity开发、.Net培训、期待与您交流!--------------------------
面向对象的特征:封装、继承和多态
封装:即将不需要对外提供的具体的实现细节,来隐藏起来,而仅提供公共访问方式。如,类是一个封装体,函数是一个封装体等。
上次博客已经总结了封装即类的特点。下面总结继承和多态。
------------------------------------------------------------------------------
继承
1、定义:
继承即为一个类和另一个类之间的继承关系。而父类的出现是由子类一级一级的抽取而
获得的,即父类是子类的共性内容。
2、继承的好处
第一,提供了代码的复用性;
第二,让类与类之间产生了关系,为面向对象的特点多态提供了前提。
3、继承的注意事项
继承不支持多继承,只继承单继承,但支持多层继承。因为若一个类可以同时继承多个父类
则当父类之间出现了相同功能时,子类使用时会不知道该调用哪一个功能。所以java不支持多继承
但java保留这种机制,并用另一种体现形式--多实现来完成。
4、继承的特点
第一,继承用到的关键字为extends
第二,对于一个继承体系的使用,是查阅父类中的方法,而创建最底层子类的对象。
5、继承中类的各个成员的特点
------------------------------------------------------------------------------
继承中类的各个成员的特点
成员变量
1、当父类和子类中有同名的成员变量的定义时,则当子类对象调用时,默认使用的是子类中的成员变量。
要想使用父类的成员变量,则在使用变量的前面加上super。
例子:
class Fu
{
int num=4;
}
class Zi extends Fu
{
int num=5;
void show()
{
System.out.println(num);//此时结果为5,因为默认的是this.num
System.out.println(super.num);//结果为4,即调用的是父类中的变量。
}
}
class BianLiangTest
{
public static void main(String[] args)
{
Zi z=new Zi();
z.show();
}
}
2、this和superthis:表示本类对象。但是本类的对象那么多,到底代表哪个对象呢?this代表的是调用
它所在的函数的本类对象。
super:表示的是子类的父类的引用。
------------------------------------------------------------------------------
成员函数
1、子类可以直接继承父类中的函数,也可以根据自己的情况将父类中具有的功能主体自己再重新
写一次,即出现了子父类间函数的覆盖现象。
2、覆盖的特点
第一,父类和子类中功能的定义一样,但是功能主体不一样。
第二,当子类对象调用该功能时,会运行子类中的此功能,如同父类的函数被覆盖一样。
3、子类函数覆盖父类函数的条件
子类函数的权限必须大于等于父类函数的权限。
注意,静态只能覆盖静态。
4、由覆盖而产生的思想
当在原来的功能的前提下再添加新的功能时,并没有必要去修改原来的功能,而是利用覆盖
的特点来实现添加功能,并在此新的功能主体中调用原来的功能即可。
例子:
class Tel
{
void show()
{
System.out.println("number");
}
}
class NewTel extends Tel
{
void show()//复写了父类的相同功能
{
super.show();//调用父类的原有功能
System.out.println("name");//增加新的功能
System.out.println("pic");
}
}
class MethodTest
{
public static void main(String[] args)
{
NewTel nt=new NewTel();
nt.show();
}
}
------------------------------------------------------------------------------
构造函数
1、构造函数之间无覆盖功能。但是子类的构造函数会调用父类的构造函数,利用super语句
子类构造函数之间也可以调用,通过this语句。
2、子类的构造函数中至少有一个构造函数默认的第一行有一条隐式的语句super(),来调用父
类的构造函数。
例子:
class Fu
{
Fu()
{
System.out.println("Fu-----run");
}
}
class Zi extends Fu
{
Zi()
{
//默认有super()
System.out.println("Zi--run");
}
Zi(int num)
{
this();//当子类构造函数的首句是this()语句时,则就没有默认的super()语句了
System.out.println("Zi-----------num");
}
}
class ConstructorTest
{
public static void main(String[] args)
{
Zi z=new Zi();//最终结果为Fu-----run
// Zi--run
}
}
3、当父类中无空参数的构造函数时,则子类中必须手写上一句super(参数)语句,与父类中的构造函数一样,参数填父类构造函数参数的类型的值。
例子:
class Fu
{
Fu(int x)
{
System.out.println("Fu-----x");
}
}
class Zi extends Fu
{
Zi()
{
//由于父类无无参的构造函数,所以此处手冻的写上
super(3);
System.out.println("Zi--run");
}
Zi(int num)
{
this();//当子类构造函数的首句是this()语句时,则就没有默认的super()语句了
System.out.println("Zi-----------num");
}
}
class ConstructorTest
{
public static void main(String[] args)
{
Zi z=new Zi();//最终结果为Fu-----3
// Zi--run
Zi z2=new Zi(4);//结果为Fu-----3
//结果为Zi----------4
}
}
4、this语句和super语句this语句是用于本类构造函数之间的调用。
super语句是用于子类调用父类构造函数。
这两个语句都必须写在构造函数的第一行。所以这两句在构造函数中是不能同时出现的。
5、为什么子类的构造函数的首句一定要访问父类的构造函数的呢?
因为父类中的数据子类是需要继承的,那么子类在创建对象并对对象进行初始化时,应该
先要看看父类中是怎么对数据进行初始化的。所以子类的构造函数的首句要访问父类的构造函数。
6、总结
第一,子类的所有的构造函数,默认都会访问父类中空参数的构造函数,因为子类每一个构造函数
的首句都有一句隐式的super()语句。
第二,当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中
的构造函数。
第三,当然,子类中的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。但是
子类中至少有一个构造函数会访问父类中的构造函数。
------------------------------------------------------------------------------
抽象类
1、格式:abstract class Student
{
}
2、抽象类的运用
当多个类中出现相同功能,但是功能主体不同,这时可以进行向上抽取,只抽取功能定义
,而不抽取功能主体。这样将抽取的功能定义就封装到一个抽象类中。让子类来具体实现这些
抽象功能。
3、抽象类的特点
第一,抽象方法一定定义在抽象类中;
第二,抽象方法和抽象类都必须被abstract关键字修饰;
第三,抽象类不可以创建对象,因为调用抽象方法没意义;
第四,抽象类中的方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用,
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
第五,抽象类中可以有抽象方法,也可以没有,那么此抽象类只是为了不让创建它的对象。
4、抽象类和一般类的区别
抽象类和一般类没有太大区别,该怎么描述事物就怎么描述事物,只不过该事物出现了一些
看不懂的东西,这些不确定的部分,也是该事物的功能,需要明确出现,但是无法定主体,所以
通过抽象方法来表示。
5、由抽象类而总结出的编程思想:模板方法设计模式
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,
那么这时就将不确定的部分暴露出来,定义为抽象的,由该类的子类去完成。
例子:
/**
需求:获取一段程序的运行时间。
步骤:
1.定义一个获取时间的类
2.类中定义一个函数,用来获取时间
3.用一个函数单独用来记录运行的程序
模板方法设计模式:
定义:在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,
而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露
出来(即抽象化),由该类的子类去完成(即在子类中将此方法进行复写)。
*/
abstract class GetTime
{
public void getTime()
{
long start=System.currentTimeMillis();
runCode();
long end=System.currentTimeMillis();
System.out.println("time="+(end-start));
}
//由于此程序并不确定,所以抽象出来
public abstract void runCode();
}
//此抽象方法由子类来具体实现
class SubTime extends GetTime
{
public void runCode()
{
for (int x=0;x<400 ;x++ )
{
if (x%2==0)
{
System.out.println(x);
}
}
}
}
class GetTimeDemo
{
public static void main(String[] args)
{
SubTime st=new SubTime();
st.getTime();
}
}
------------------------------------------------------------------------------
接口
1、接口用interface来定义,并且接口可以看成是程序的功能扩展。
2、接口定义时,格式特点:
第一,接口中常见定义:常量,抽象方法
第二,接口中的成员都有固定修饰符
即:常量:public static final eg:public atatic final int NUM=4;
方法:public abstract eg:public abstract void show();
3、注意接口中的成员都是public的
4、接口是不可以创建对象的,因为接口中的方法都是抽象的,需要被子类实现,子类对
接口中的抽象方法全都覆盖后,子类才可以实例化,否则子类是一个抽象类。
5、接口可以被多实现(即一个类可以实现多个接口),也是对多继承不支持的补充。
6、接口和抽象类的不同是,抽象类中可以有构造方法,而接口中没有。
7、类在继承的基础上可以多实现。
8、接口和接口之间是实现:extends 并且接口之间可以多继承。
类与类之间是继承:extends
类与接口之间是继承:implements
例如:
interface A
{
}
interface B
{
}
class C
{
}
class D extends C implements A,B
{
}
-------------------------ASP.Net+Unity开发、.Net培训、期待与您交流!--------------------------
详情请查看:http://edu.csdn.net