导读:继承概述,聚集关系,子父类中变量关系,子父类中函数覆盖,子父类中构造函数,final关键字,抽象类,
模板方式设计模式,接口,接口特点
1、继承概述
l 面向对象的第二种特征:继承
Ø 类本身就是一种抽象的行为。父类的由来是由子类抽取而来的。
Ø 例:人—学生—工人
Ø 将学生和工人的共性描述提取出来,单独进行描述,只要让学生和工人与单独描述的这个类有关系,就可以了。
Ø Student是person的子类。Person就是Student这个类的父类。Person也叫做基类或者超类
l 继承:
(1)提高了代码的复用性。
(2)让类与类之间产生了关系。有了这个关系,才有了多态的特性。
注意:
千万不要为了获取其他类的功能,简化代码而继承。必须是类与类之间有所属关系才可以继承。所属关系是谁是谁中的一种(is a)。
l 怎样判断两个类中有没有关系?
可在继承一下,看看父类中的内容是不是子类中都应该具备的。如果父类中有的功能不是子类应该具备的,则不应该继承。
l Java语言中:java只支持单继承,不支持多继承。因为我继承容易带来安全隐患。因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪一个。但是java保留这种机制。并用另一种体现形式来完成表示(多实现)。
l java支持多层继承。也就是一个继承体系(C继承自B,B继承自A。C是孙子,B是父亲,A是爷爷)
l 如何使用一个继承体系中的功能呢?
Ø 想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。通过了解共性功能,就可以知道该体系的基本功能。那么这个体系已经可以基本使用了。
Ø 为什么在具体调用时,要创建最子类的对象呢?
一是因为有可能父类不能创建对象(抽像类和接口),二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。
Ø 简单一句话:查阅父类功能,创建子类对象使用功能。
2、聚集关系
l 类与类之间,对象和对象之间,事物和事物只间不仅只有继承这一种。还有组合关系。
l 聚集,即谁里边有谁(has a),它又分为聚合和组合。它们的紧密联系程度稍有不同。
Ø 聚合:球队—球员 球员是球队中的一员。
Ø 组合:事物的联系更紧密。手和身体。手是身体必不可少的一部分。
3、子父类中的关系—变量
l 如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this。子类要访问父类中的同名变量,用super。super的使用和this的使用几乎一致。this代表的是本类对象的引用。super代表的是父类对象的引用。
class Fu
{
private int num = 4;
}
class Zi extendsFu
{
void show()
{
System.out.println(this.num);//this.num和super.num打印出来的都是4,可以有两种现解方式。第一:Zi继承自Fu所以子中也有一个num。第二:this和super指向同一个对象(对象中有num)。(多态,父类引用指向子类对象)
}
}
class ExtendsDemo2
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
}
}
一new的话,要加载Zi的.class文件,加载Zi.class文件的时候它会先加载Fu.class文件。子类中不仅有一个this对象,还有一个super对象。
4、子父类中函数的特点—覆盖
l 覆盖也称之为重写。当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。
当子类继承父类,沿袭了父类的功能,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新功能,而是使用覆盖技术,保留父类的功能定义,并重写功能内容。利用复写的特性,给程序提高扩展性。(继承,复写)
l 覆盖:
(1)子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
(2)静态只能覆盖静态。
l 重载和重写的区别:(重载和重写完全不一样的)
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。(包括返回值类型)
l 升级的话,千万不要改源码。如果要修改原来的代码一定是一个灾难。因为改的话,不会改一处,动一下就是动一片。而这一片又被另外一片调用,你又得调另外一片。所以初期的时候把源码设计的好一点,方便扩展。
5、子父类中构造函数的特点—子类实例化过程
l 子父类构造函数能一样吗?
不能,因为构造函数是跟着类名走的,类名是不能一样的。
l 在对子类对象进行初始化时,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句 super();表示调用父类的构造函数。super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();
l 为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数(先参考一下父类的初始化,再看一下自己要不要重新初始化)。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。(父类中构造构造函数是隐式的子类中也可以是隐式的,如果父类中的构造函数不是隐式的,子类中也要不是隐式的,用super(4);等语句显式表示,传入参数。)
注意:super语句一定定义在子类构造函数的第一行。(老的不能用,再用自己的,不能反了)
l 子类的实例化过程—结论:
子类的所有的构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式super();当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数(构造函数中要么有this();语句,要么有super();语句)。
l 父类中已经定义好的东西,子类中没有必要重新定义,直接用就可以,只是调用构造函数,用super(name)等; 不是调用构造函数用super.show();
l 在Java中所有类的父类都上继自Object。
6、final关键字
l 继承一个蔽端,打破了封装性。
l final : 最终。作为一个修饰符,
(1)可以修饰类,函数,变量。
(2)被final修饰的类不可以被继承(在类前面加上final 使类成为最终类,所有方法都不能被复写)。为了避免被继承,被子类复写功能。
(3)被final修饰的方法不可以被复写。
(4)被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成。单词间通过_连接。
(5)内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
l 在写代码的时候出现了一些固定数据,即使只出现一次也要起一个名字。读名字要比数字更快更方便。
public static final double PI = 3.14全局常量。权限够大,类名调用,值不会变。
7、抽象类
l 看不懂就是抽象的东西。(例如,狼和狗共性都是犬科,犬科就是抽象出来的概念。)
抽象类和一般类没有太大的不同。该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体。并通过抽象方法来表示。
l 当多个类中出现相同功能,但是功能主体不同,这是可以进行向上抽取。这时,只抽取功能定义,而不抽取功能主体({ }中的东西)。(功能定义和功能主体相同可以抽取一个方法)(例如:狼和狗都有吼叫的方法,可是吼叫内容是不一样的。所以抽象出来的犬科虽然有吼叫功能,但是并不明确吼叫的细节。)
l 抽象类的特点:
(1)抽象方法一定在抽象类中。
(2)抽象方法和抽象类都必须被abstract关键字修饰。
(3)抽象类不可以用new创建对象(不可以实例化)。因为调用抽象方法没意义(无执行体)。例如:犬科是一个抽象的概念,真正存在的是狼和狗。
(4)抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
不抽象的话,父类中的方法,在子类中可以复写,也可以不复写。但如果父类抽象的话,子类必须要复写。强迫的去做一些事情。
l 抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。
l Abstract只是用来定义抽象类和抽象的方法,不定义常量。
l 抽象类中可不可以没有抽象方法?
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
(具体实现方式不一样的方法可定义成抽象的方法,实现方式都一样的方法可以在抽象类中定义一个方法,并将功能主体实现。)
l 抽象类中是否有构造函数?
有,抽象类是一个父类,要给子类提供实例的初始化。
l abstract 关键字,和哪些关键字不能共存?
Ø final:被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
Ø private: 抽象类中的私有的抽象方法,不被子类所知,就无法被复写。而抽象方法出现的就是需要被复写。
Ø static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。
8、模板方法设计模式
l 一个函数中有一部分代码是另一个函数中要用到的,可以将一个函数中的代码变成多个函数。因为函数是用来封装代码的。
l 第一提高了扩展性,第二,提高了利用性。
l 例:月饼—馅
l 什么是模版方法呢?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去。由该类的子类去完成。
l 需求:获取一段程序运行的时间。
原理:获取程序开始和结束的时间并相减即可。
abstract classGetTime
{
public final void getTime() //强制避免复写。(不需要,可以不写)
{
long start =System.currentTimeMillis(); //获取时间
runcode();
long end =System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
public abstract void runcode(); //模板方法通常有抽象类,但这个方法不一定总是抽象的。有这种情况:我有默认的实现,你感觉我的不好,你可以写你的,我以你的为主。
}
class SubTimeextends GetTime
{
public void runcode()
{
for(int x=0; x<4000; x++)
{
System.out.print(x);
}
}
}
class TemplateDemo
{
public static void main(String[] args)
{
SubTime gt = new SubTime();
gt.getTime();
}
}
9、接口
l 接口:初期理解,可以认为是一个特殊的抽象类,当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
l class用于定义类,interface 用于定义接口(可以理解为特殊类,编译后产生.class文件)。
l 接口定义时,格式特点:
(1)接口中常见定义:常量,抽象方法。
(2)接口中的成员都有固定修饰符。(少写什么给你补什么,少写的话,可读性不好)
常量:public static final 方法:public abstract
记住:接口中的成员都是public的。
l 类和类之间是继承关系,到接口这里就成为实现(implements)关系。
Ø 接口:是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化(比较:在继承中子类可以直接用父类的东西)。否则子类是一个抽象类。
Ø 抽象类的范围你可以随便设定,而接口全部都是固定的,为public。
Ø 接口可以被类多实现(一个类可能实现多个接口),也是对多继承不支持(父类中的方法有重复,子类在调用的时候会有问题)的转换形式。java支持多实现。(为什么接口就没有继承的安全性问题呢?因为接口中有方法都是抽象的,没有方法体,可以由子类任意定义。子类重写方法的话,会把多个接口中的相同的方法都给覆盖了)
interface Inter
{
public static final int NUM = 3;
public abstract void show();
}
class Test implements Inter
{
public void show(){}
}
classInterfaceDemo
{
public static void main(String[] args)
{
Test t = new Test();
System.out.println(t.NUM); //三种方式都可以。但是有一个不能做:对NUM赋值。
System.out.println(Test.NUM);
System.out.println(Inter.NUM); //接口名调用成员
}
}
l class Testextends Demo implements Inter,InterA,一个类在继承了父类的同时,还可以实现多个接口。可以扩展这个类的功能。
类和类之间是继承的关系,类和接口这间是实现关系,接口和接口之间也是继承关系。
interface A
{
void methodA();
}
interface B extendsA //接口继承自接口
{
void methodB();
}
interface C extends B
//如果B没有继承自A的话,C可以直接继承自A和B。interface C extends B,A
{
void methodC();
}
class Dimplements C
{
public void methodA(){} //要实现三个方法。
public void methodC(){}
public void methodB(){}
}
l Java支不支持多继承?支持多继承。但是只在接口和接口之间支持多继承。
10、接口的特点
l 接口是对外暴露的规则。
l 接口是程序的功能扩展。
l 接口的出现降低耦合性。(模块式开发)
l 接口可以用来多实现。
l 类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
l 接口与接口之间可以有继承关系。
例(笔记本,插座,)
u 以CPU和其插槽为例,插槽出现了之后有什么好处?
很多CPU都能往上插,提高了主板的功能。这个插槽就是接口。
u 继承是“你是我中的一种(is a)”,接口是“一种扩展功能(like a)”
例:class ZhangSan extends Student implements Smoking
u 基本功能定义在类中,扩展功能定义在接口中。
找到组织(体系)是继承,搞点副业(体系外)是接口
------- android培训 、 java培训 、期待与您交流! ----------