------- android培训、java培训、期待与您交流! ----------
继承
特点:就是将类与类之间,共性的属性和行为,进行独立进行封装
让类与类之间产生关系
好处:
提高了代码的复用性。
因为关系给多态这个特征提供了前提
多个类中存在相同属性和行为时,可以将这些内容抽取到单独一个类中,
那么多个类无需再定义这些属性和行为,只要继承那个类即可
多个类可以称为子类,单独这个类称为父类 超类、基类
子类可以直接访问父类中的非私有的属性和行为
在JAVA中继承的体现
1、 java中只支持单继承。不直接支持多继承,保留了多继承机制,用另一种来体现
2、java还支持多层继承(b继承a ,c继承b, d继承c);
父类是通过不断的向上抽取共性内容而来的。
继承体系
想要使用一个体系:就查看该体系中顶层类中的内容,
因为该 类中定义了该体系的最基础最共性功能
当使用该体系时,创建对象最好以最子类为主
简单说:
使用一个体系
查阅父类内容,创建子类对象
什么时候定义继承??
当类与类之间存在着所属关系(is a )时,就可以使用继承
其实就是什么是什么(XXX是YYY)中的一种,就可以称为继承 xxx extends yyy
父类中的功能是不是你都该具备的吗??
实在分不清楚,那就判断如果真的继承了,父类中的内容子类是否真可以具备
如果有不可以或者不需要具备的,那么就不要继承
例如:
class a{}
class b extends a{} //单继承 java 只支持单继承
class c extends a,b //多继承 但是JAVA 里面不支持
为什么不支持多继承??
例如:
class a
{
void show()
{
System.out.println("a");
}
}
class b
{
void show()
{
System.out.println("b");
}
}
class c extends b,a
{
new c().show(); //就会产生不确定性
}
当c继承a、b时,c 来调用父类的方法时,无法确定是调那个父类的方法。
一个孩子只能有一个父亲,但是一父亲能有多个孩子
--------------------------
子父类的成员的特点
1、成员变量
2、成员函数
3、构造函数
对于同名成员变量的
super和 this的用法很相像
不同之处在于
this:代表的是一个对象
super:代表的是父类所属的空间
注意:一般情况下,不会出现该种同名情况
class Fu
{
int num=3; //成员的变量
}
class zi extends Fu
{
int num2=4;
public void show()
{
int num=5;
System.out.println(this.num); //如果想打印4 就是要在变量前面加标示 this.num
System.out.println(super.num);//如果想打印父类的3 就是要在变量前面加标示 super.num
}
}
class Extends Demo2
{
public static void main()
{
Zi z=new Zi();
z.show();
}
}
当子父类中出现了同名的成员变量时,如果在子类中使用父类中的变量
需要通过super关键字来区分
如果子类的方法里面有变量时,就会使用方法里面的变量,这就是java的就近原则
当子类里面也有变量的时候 ,java就会直接显示子类里面的变量
如果方法里面还有变量,那就会显示方法里面的那个变量的值
----------------------------------------------------
子父类中的成员函数
当子父类中出现了一模一样的方法
这种情况,我们称之为:函数的一个在子父类中特性:覆盖(override) 重写
class Fu
{
public void show()
{
System.out.println(“FU SHOW”);
}
}
class zi extends Fu
{
public void show()
{
super.show();
System.out.println("ZI SHOW");
}
}
class Extends Demo2
{
public static void main()
{
Zi z=new Zi();
z.show();
}
}
当子类运行 z.show()时,如果子类中有这个方法,子类就会先调用自己的方法,
如果没有就会通过super()来调用父类的方法。
覆盖的应用:
对于后期功能的扩展,不建议对原有代码进行修改
学习了继承,可以通过对已有类进行子类的扩展来完成功能的定义
如果是对原有的类已有功能进行改写
只需要保留原有类的功能声明。重新定义 功能的主体内容,即可
这是是覆盖的应用
如果子父类都有相同的方法,但是在保证父类的功能方法不变的情况下,那就可以通过覆盖来完成
将父类原有的功能保留,在子类中重新定义功能,在调用父类的方法。super.show();
调用父类的方法。
例如: 移动手机
覆盖的注意事项:
1、必须要保证返回值 类型 函数名 参数列表要一模一样
2、子类覆盖父类时,必须要保证权限大于等于父类
3、覆盖中,如果有一方是静态,那么另一方必须是静态
只要在调用中出现不确定情,java 就会报错啊
所以在程度中不能出现。
-------------------------------------------------
子父类的构造函数
通过结果发现,父类中的构造函数先运行,然后才运行子类的构造函数内容
为什么了?
因为在子类的构造函数的第一行默认都有一条隐式的 super();
在默认调用父类中的空参数构造函数
为什么子类的构造函数必须要访问父类中的构造函数?
子类继承了父类,可以使用父类中的数据,在使用前,应该先看一下父类是如何对该数据进行初始化的
所以子类的构造函数都必须在初始化前先执行父类的构造函数
这也是子类的实例化过程
class Fu
{
Fu()
{
System.out.println("fu run");
}
}
class zi extends Fu
{
Zi()
{
//super(); 默认的父类的空参数构造函数
System.out.println("zi run");
}
}
}
class Extends Demo2
{
public static void main()
{
Zi z=new Zi();
z.show();
}
}
子类的构造函数默认都访问父类中的空参数构造函数
如果父类中没有空参数构造函数,或者子类要访问父类中指定的构造函数
那么必须在子类中用显示的super语句明确要访问哪个父类的构造函数
super语句中必须要定义在子类构造函数的第一行?
因为父类初始化动作要先执行。
this 语句 和super语句 可以同时存在吗?
不可以
为什么this(),super()必须定义在构造函数的第一行
因为初始化值要先执行
*****类加了什么权限,那方法里面的默认权限就是和类相同
应用
class Person
{
private String name;
private int age;
Person(String nam,int age)
{
this.name=name;
this.age=age;
}
}
class Student extends Person
{
Student(String name,int age)
{
//this.name=name;
//this.age=age;
super(name,age);
}
public void study()
{
}
}
因为父类的属性是私有了。在就是父类已经把这些事情已经做完了。
我们只要调用就可以了。但是这个函数是构造函数
直接通过父类的super()进行参数的传递
就是父类把事情做了。子类就只要直接去调用它就可以了
-----------------------------------------
覆盖只发生子父类的函数上
继承的弊端:打破了封闭性
final(最终)关键字
final可以修饰类,可以修饰方法,可以修饰变量
final修饰的类不可以被继承
final修饰的方法不可以被覆盖
final修饰的变量是一个常量,只能被显示赋值一次
其实就 是为了给固定的常量起个名字,并用final修饰后,该名称的值就固定了
这是为了增加程序的阅读性,只要是被final修饰的常量,
名称有规范。所有字母都 大写,如果由多个单词组成的, 用_分隔
只要有固定的数据出现,就用定义名称将其记录,并用final修饰
例如:
final class Fu //被final修饰的类不可以被继承
{
final int num; //因为有默认值,所以会报错。
被final修饰的必须要显示初始化值 且只能进行一次赋值
final void show() //final修饰方法
{
}
}
class Zi extends Fu
{
void show()
{
final int nun=4; //被final修饰的变量只能进行一次显示赋值
}
}
public static int num=9; 全局变量
加final后就叫全局变量
----------------------------------------------
抽象类
例如:
犬科(狼、狗)
abstract class 犬科
{
abstract 吼叫();
}
class 狼 extends 犬科
{
void 吼叫()
{
System.out.println("嗷嗷");
}
}
class 狗 extends 犬科
{
void 吼叫()
{
System.out.println("汪汪");
}
抽象类的概述
其实就是具体的事物不断地向上抽取而来的
而且只抽取了方法的声明,而没有抽取方法的实现
所以该方法是抽象方法,而抽象方法必须存储在抽象类中
抽象类:其实就是对事物的描述,定义了事物的具体的基本的功能,但是有些功能不确定具体的内容
这个内容有其子类完成的具体的内容的定义
抽象类的特点:
1、没有方法主体的方法是抽象方法,必须定义在抽象类中
抽象方法和抽象类必须用abstract关键字修饰
2、抽象类不可以被实例化,也就是说,不可以用new创建对象。因为调用抽象方法没有意义
3、抽象类必须由自己的子类覆盖了所有的抽象方法后,其子类才可以被实例化,否则,该子类还是一个抽象类
抽象类的细节
1、抽象类中是否有构造函数
有的,抽象类的构造函是给子类进行初始化的
抽象类和非抽象类异同点:
相同:
抽象类和非抽象类都是用于描述事物
都可以定义类中应该有的成员。成员变量、成员函数、构造函数
不同:
抽象类可以定义抽象方法,非抽象类不行
抽象类不可以实例化,而非抽象类可以实例化
2、抽象类中可不可以不定义抽象方法?
可以的。如果抽象类中没有定义 抽象方法,那么目的是一个,就是不让该类创建对象
这种情况有,在awt中的适配器类就是如此,但是不多
3、抽象关键字不可以和哪些关键字共存?
private :如果加了private 那就是子类不知道 你有这个方法了。
static : 如果加static 静态了 就可以用类名.方法名进行调用了。所以用抽象就没有意义 了
final; 会出现提示显示无非法的组合
------- android培训、java培训、期待与您交流! ----------