/*
索引:1.继承概述
2.子父类变量特点
3.final关键字
*/
/*
无论Student类、Teacher类还是Worker类,他们都是人,共同拥有年龄、姓名、性别等属性,将其提取出来单独创建一个Person类来描述。
这样,Student类、Teacher类和Worker类就是Person类的子类,后者就是前边三者的父类(实际父类是由不断抽取子类而来的),子类继
承父类的内容属性(name、gender、age),而Student类、Teacher类和Worker类下还有具体的对象(如具体的学生Ryan、Tracy等)作为
其子类,他们同样拥有其子类的共有属性(name、gender、age、study、work、teach等),这样的思想就是继承:父类拥有子类的共有属
性,子类继承父类属性且不再单独描述,只需在其类名后加上extends关键字和父类类名即可,详见下例。
好处:1.提高代码的复用性;2.使类与类间产生关系,才有了多态的特性(多态:面向对象的第三个特征)。
缺点:因其可被任意类所继承,从而可被任意类所覆盖,这样会打破封装性。
注意:千万不可只是为了获取其他类的功能、简化代码而继承,必须是类与类间有所属关系才可继承,所属关系:is、a。
java中只支持单继承(即一个子类同时只能继承一个父类),不支持多继承(一个字类同时继承多个父类,此处不支持多继承优化了C++的
对应功能,但其保留了这种机制,采用多实现的形式来表示),因为后者易带来安全隐患(原理:当多个父类中定义了相同功能且功能内容
不一样时,子类不确定要执行哪一个)。
java支持多层继承,即一个继承体系
如何使用继承体系中的功能?
1.先查阅父类的描述,从而了解该体系的共性功能,此时这个体系就可以基本使用了。
2.具体调用时,创建最子类的对象,原因:1.父类(抽象类、接口)有可能无法创建对象;2.可以使用更多功能(基本、特有的)。
*/
class Person //抽象类
{
String name, gender;
int age;
}
class Student extends Person //抽象类
{
void study()
{
System.out.println("good study");
}
}
class Worker extends Person //抽象类
{
void work
{
System.out.println("good job!");
}
}
class Teacher extends Person //抽象类
{
void teach
{
System.out.println("study hard");
}
}
class Extends
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
/*
子父类变量特点(详见下例):
类中成员:1.变量;2.函数;3.构造函数;
*/
//1.变量:子类中出现非私有的同名成员变量(很少出现,因其重复)时,this引用本类对象,super引用父类对象
//子父类在内存中的实际情况见笔记07天:例.子父类
class Father
{
int num = 5;
void Info()
{
}
}
class Son extends Father //执行Son类时,因其继承Father类,所以先执行Father类
{
int num = 7;
void show()
{
System.out.println(num); //此处num前边省略了关键字this,代表本类对象,用super代表父类对象
//若此处子类中未定义num,父类中定义了num,那么无论使用this还是
//super都会引用父类中的num,这就是多态:父类引用对象指向子类。
}
}
class Extends2
{
public static void main(String[] args)
{
Son s = new Son();
}
}
//2.函数
/*
当子父类中出现同样的函数时,会执行子类的函数内容,好像父类的函数(仍在
内存中只是没有被执行)被覆盖一样,这就是覆盖(也称重写:函数的一种特性)。
当子父类具有相同功能但具体内容不一致时可以使用覆盖(子类沿袭父类功能并定义
特有内容),应用:功能扩展(方式:用super引用父类功能,子类定义新增功能,
一定不能通过修改源码的方式进行)。
覆盖需注意:1.必须保证子类权限大于等于父类权限(但不可用private修饰);
2.静态只能覆盖静态(不常用);
重载、覆盖(复写)的区别:前者只看同名函数的参数列表,后者要求子父类方法一
模一样(包括返回值类型)。
*/
class Father2
{
void show()
{
System.out.println("Class Father");
}
}
class Son2 extends Father2
void show()
{
System.out.println("Class Son");
}
}
class Extends3
{
public static void main(String[] args)
{
Son2 s = new Son2();
s.show(); //当子父类中出现同样的函数时,会执行子类的函数内容,好像父类的函数(仍在
//内存中只是没有被执行)被覆盖一样,这就是覆盖(也称重写:函数的一种特性)。
}
}
//3.构造函数
/*
子类构造函数无法覆盖父类构造函数,因为构造函数随类名变化,子父类的构造函数一定不同,故无法覆盖。
子类的实例化过程:
子类中的所有构造函数默认都会访问父类中空参数的构造函数,所有子类函数第一行均有一条super();语句,
它调用父类的空参数构造函数(默认),若想调用其他的父类构造函数,则用super语句即可,若父类中无默
认构造函数,则子类必须用super手动调用其他构造函数。子类构造函数可直接调用父类构造函数,省去自己
初始化。super一定要放在子类构造函数的第一行,this也如此放置,所以构造函数第一行只能存在this、super
之一,子类中至少有一个构造函数访问父类的构造函数。
子类必须访问父类构造函数的原因:
因为子类可直接获取父类的数据,所以子类对象在建立时需查看父类是如何对这些数据进行初始化的,故
子类在初始化时要先访问父类的构造函数。
java中所有类的父类:Object
*/
class Father3
{
Father3();
{
System.out.println("Class Father3");
}
}
class Son3
{
Son3();
{
//此处隐式一条super();语句,其会调用父类的空参数构造函数,这条语句在所有子类函数第一行均存在,同理this();调用子类构造函数
System.out.println("Class Son3");
}
}
class Extends4
{
public static void main(String[] args)
{
Son3 s = new Son3;
}
}
/*
final:最终,一种修饰符
特点:1.可以修饰类、函数、变量。
2.被final修饰的类不可以被继承。
3.被final修饰的方法不可以被覆盖。
4.被final修饰的变量是一个常量只能被赋值一次(用途:事物描述中出现的一些
有固定值的数据,如圆周率PI(π)=3.1415926...),可以修饰成员和局部变
量。常量书写规范:所有字母都大写,多单词间用下划线连接。
5.内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
*/
|
|