------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、继承
1、继承的概念
继承,就是在已存在的类的基础上,进行扩展,从而产生新的类。已经定义好的类称为父类。在JAVA中,父类所拥有的一切,子类都可以继承。在父类中中定义的非私有的属性和方法,子类都可以继承。在子类继承父类后就自动获得了父类的非私有属性和非私有的方法。子类可以直接使用他们而不用自己再进行定义。
继承是面向对象的一个重要特征。当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可。
这样类与类之间就存在了继承的关系。子类可以直接访问父类中的非私有的属性和行为。在代码中通过extends关键字表示继承关系。例:
class Sonextends Father{} //这也是在代码中的书写格式。
注意:千万不要为了获取其他类中的功能,简化代码而继承。必须是类与类之间有所属关系才可以继承。这种所属关系的表示为is a.
2、继承的特性:
1、直接使用继承的父类的属性和方法,提高了代码的复用性。
2、让类与类之间产生了关系,有了这个关系,才有了多态的特性。
注:Java语言中,只支持单继承,不支持多继承。例:一个儿子只能有一个父亲。
原因:因为类与类多继承的话,容易带来安全隐患。如:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪个一个。
但是Java保留了这种机制,并用另一种体现形式来完成。叫多实现。
3、在继承时需要注意:
1、不能为了获取其他类的功能,简化代码从而随便继承。
2、要继承,必须要有所属关系。比如学生继承人,学生所属于人,人的基本属性,学生都具有。
3、JAVA中只支持单继承,不支持多继承。但是支持多实现。JAVA虽然不支持多继承但是支持多层继承。
4、继承的方法的使用
想要使用体系,先查阅体系父类的描述。因为父类中定义的是该体系中共性的功能。通过了解共性功能就可以知道该体系的基本功能。
在具体调用时,要创建最子类的对象,因为
1)可能父类不能创建对象。
2)创建子类对象可以使用更多的功能,不仅可以使用基本功能而且可以使用特有功能。
当子类创建对象时在内存中对象的建立过程:
主函数执行new Zi()——>加载Fu.class——>加载Zi.class——>分配属性空间(父类的属性不管是不是私有的和子类的属性都在子类对象里面)
方法区:
Fu类中的方法加载——>子类的方法加载——>子类除了this引用(本类引用)外还有super引用(父类引用)
5、子父类中成员的特点:
1、变量:
如果子类出现非私有的同名变量时。子类如果要访问本类中的变量用this。子类如果要访问父类中的变量,用super。(this代表本类引用,super代表父类引用。)
2、函数:
当子类出现和父类一样的函数时。子类对象调用该函数,会运行子类的内容。如同父类的函数被覆盖一样。这种情况是函数的另一个特性——重写。
当子类继承父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新的功能,而是使用覆盖特性,保留父类的功能定义并重写功能内容。
当子类覆盖父类,必须保证子类的权限大于等于父类的权限,才可以覆盖,否则编译失败。(但是如果父类中的方法被私有,此时子类不知道父类有那个方法,所以不能算是覆盖)
3、构造函数:
在对子类对象进行初始化事,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐士的语句super();super();会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super();
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。
子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。
注意:super语句一定定义在子类构造函数的第一行
二、final关键字
继承的出现,打破了对象的封装性,使得子类可以随意复写父类中的功能。这也是继承的一大弊端。那么怎么解决这个问题呢?这里就引出了一个新的关键字——final(最终)。
Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。
1、被final修饰的特性:
1)final类不能被继承,没有子类,final类中的方法默认是final的。
2)final方法不能被子类的方法覆盖,但可以被继承。
3)final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
4)final不能用于修饰构造方法。
注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。
2、final修饰对象:
1)类:final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。
2)方法:如果一个类不允许其子类覆盖某个方法,则可以把这个方法定义成final类型。
3)变量(常量):用final修饰的成员变量表示常量,值一旦给定就无法改变!final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。
特别说明:final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。
三、抽象类
Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。
抽象类的由来:
多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。
抽象就是将对象的共同方法和属性提取出来,提取后,重新设计一个更加通用类,这个类被称为抽象类。
1、抽象类的特点
1、抽象类和抽象方法必须用abstract关键字来修饰。
2、抽象方法只有方法声明,没有方法体,定义在抽象类中。
格式:修饰符abstract返回值类型 函数名(参数列表);
3、抽象类不可以被实例化,也就是不可以用new创建对象。原因如下:
1)抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例;
2)而且抽象类即使创建了对象,调用抽象方法也没有意义。
4、抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。
注:抽象类中可以有非抽象的方法。
2、什么时候定义抽象类?
当多个类中出现相同功能,但是功能主题不同的时,就可以向上抽取,这时,只有抽取功能定义,而不抽取功能主体。
抽象类的定义:
1)在类和抽象的方法前面都必须家abstract声明。
2)抽象方法一定在抽象类中。
3)抽象方法和抽象类都要声明。
4)抽象类不可以用new创建对象,因为调用抽象方法没有意义。
抽象类中的方法要被使用,必须有子类复写所有的抽象方法后,建立子类对象调用。如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
注意:抽象类中既可以定义抽象方法,也可以定义普通方法(也可以不定义抽象方法,这样做的目的是为了防止建立该类的对象)
3、抽象类与一般类的区别
1、抽象类和一般类没有太大的不同。该如何描述事物,还是如何描述事物。只不过,该事物中出现了一些不知道具体内容的方法部分。这些不确定的部分,也是该事物的功能,需要明确出来,但是无法定义主体。通过抽象方法来表示。
2、抽象类比一般类多了个抽象函数。就是在类中可以定义抽象方法。
3、抽象类不可以实例化。
4、抽象类虽然不能创建对象,但是也有构造函数。供子类实例化调用。
注:1)被abstract修饰的函数不能同时被private、final、static修饰。
原因:
final:被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
private:抽象类中的私有的抽象方法,不被子类所知,就无法被复写。
而抽象方法出现的就是需要被复写。
static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。
可是抽象方法运行没意义。
2)抽象有一个特殊的地方:抽象类中可以不定义抽象方法。这样做可以不让本来实例化,也可以用于模块设计。
4、模版设计方法
模版方法:
在定义功能时,功能的一部分是确定的,一部分是不确定的,而确定的部分在使用不确定的部分,那么这时就将确定的部分用final修饰起来,表示本方法在本类中就是具备这个确定部分的功能,不可以被复写;将不确定的部分暴漏出去用abstract修饰,由该类的子类复写去完成。
四、接口
1、接口的概念
接口,可以被认为是一个特殊的抽象类。当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。接口使用interface来表示,子类中用implements实现。
格式为: interface 接口名{}
子类名 implements接口名{}
格式特点:
1、接口中常见定义:常量,抽象方法。
2、接口中的成员都有固定修饰符。
常量:publicstatic final
方法:publicabstract
3、接口中的成员都是public的。
在使用中,常量可以不写public static final,方法可以不写public abstract,编译时Java会自动添加这些修饰符,因为这是固定的格式修饰符。但为了方便阅读,通常我们都写上。
接口与接口的关系:继承关系。接口之间可以多继承。
2、接口的特点
1、接口是对外暴露的规则。
2、接口是程序的功能扩展。
3、接口的出现降低耦合性。
4、接口可以用来多实现。这也是对多继承不支持的转换形式。java支持多实现。
5、类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
6、 接口与接口之间可以有继承关系。而且可以多继承。
注:1)接口不可以创建对象的,因为有抽象方法。需要被子类实现(implements),子类对接口中的抽象方法全都覆盖后,子类才可以实例化。否则子类是一个抽象类。
2)实现多个接口时,接口中不可以有返回不同类型的同名抽象函数。这样子类实现时将不能复写。
3、接口的使用
类通过implements实现接口,并且类可以实现多个接口;
implements的用法和extends相似;
接口不可以创建对象,因为有抽象方法;
需要被子类实现,子类对接口中的抽象方法全部覆盖后,子类才可以实例话。否则子类仍然是一个抽象类。
4、接口与抽象类
共性:都是不断向上抽取出来的抽象的概念。
区别:
1、抽象类体现继承关系,一个类只能单继承。接口体现实现关系,一个类可以多实现。同时接口与接口之间有继承关系。
2、抽象类是继承,是 "is a "关系。接口是实现,是 "like a"关系。
3、抽象类中可以定义非抽象方法,供子类直接使用。接口的方法都是抽象,接口中的成员都有固定修饰符。
4、抽象类中可以私有变量或方法。接口中的常量和方法都是public修饰的权限
继承抽象类和实现接口的选择:
抽象类是为继承而精心设计的,接口则更多以组合的方式使用。
如果你的业务中可以抽象出一个通用的处理过程,只是某些局部传递的状态或参数有所不同,这时可以考虑使用抽象类。
当只是拓展某个功能的时候,则可以实现接口的方式去实现。基本功能定义在类中,拓展功能定义在接口中。