0701-070x 继承

4.1 继承的概述
4.2 继承的特点
4.3super关键字
4.4函数覆盖
4.5 子类的实例化过程
4.6 final关键字

------------------------------------------------------------------------------------------------------------------
现实中的事物之间存在种种共同点。

为了创建方便,我们将现实中的事物的特点进行抽取,单独进行描述.

优点:
1.提高了代码的复用性
2.让类之间产生了关系。有了这种关系,才有了多态的特性。
注意:千万不要为了获取其他类的一部分功能、简化代码就进行继承。
必须是类之间有从属关系才可以继承。(谁是谁的一种才可以。)

-----------------------------------------------------------------------------------------------------------------
java中只支持单继承,不支持多继承。然而它通过了多实现的方式保留了多继承机制;
另一方面,java还支持多重继承(儿子有个父亲,父亲有个父亲的父亲)

为什么java不支持多继承?
因为多继承容易产生冲突。如果两个父类同时实现了同名但内容不同的功能,不好判断究竟是继承了哪一个。

如何使用一个体系中的功能:、
先查阅父类,再根据子类创建对象。
父类中定义的是该体系中的共性功能。通过了解共性功能,我们可以知道该体系的基本功能。
为什么这么做?
1.父类可能是抽象类,无法直接创建对象;
2.子类实现完全,功能甚至更加丰富。

-----------------------------------------------------------------------------------------------------------------
除了继承之外,java的类之间还有许多别的关系。如组合(聚合、聚集)。
举个简单的例子来说,老虎是猫科动物的一种,这就是继承。老虎继承了猫科动物的特性。
足球队的每一个队员都属于足球队,这样的关系就是组合。
-----------------------------------------------------------------------------------------------------------------
class Fu
{
int num = 1;
}

class Zi extends Fu
{
int num = 2;
}

class ExtendsDemo2
{
public static void main(String [] args)
{
System.out.println("hi "+ num);
// System.out.println("hi "+ super.num);
}
}

研究问题:子类父类出现之后,类成员的特点发生了怎样的变化?
类成员的组成:
1.成员变量:如果子类父类中出现了非私有的同名成员变量时,子类要访问本类中的变量,用this;子类想访问父类中的同名变量时,用super。super的使用和this的使用方法几乎一致。this代表本类对象的引用,super代表父类对象的引用。
父类引用指向子类对象:多态的一种体现。

2.函数
3.构造函数


如果想要使用父类的功能,那么可以使用super关键字,取父类中的同名变量。
父类先进入方法区。
------------------------------------------------------------------------------------------------------------------
2.函数
  当子类和父类中出现一模一样的函数时,
当子类对象调用该函数,会运行子类函数的内容,如同父类的函数被覆盖一样。
这种情况是函数的另一个特性:覆盖(重写)


利用覆盖的特性,我们可以增强代码的拓展性。如果子类具备该功能函数,但期望的实现方式却与弗雷不一样,那么这时没必要定义新功能,使用覆盖技术,即可保留父类的功能定义并重写功能内容。

覆盖:
1.子类覆盖父类,必须保证子类权限大于父类权限,才可以覆盖,否则会编译失败。
2.静态只能覆盖静态。(涉及到加载先后问题)

如果子类根本没有继承小权限的父类函数,那么不算覆盖。

记住:
重载:只看同名函数的参数列表
重写(覆盖):子父类方法一模一样(含返回值类型)。如果返回值类型不一样,会报错。
------------------------------------------------------------------------------------------------------------------
3.构造函数。

子类在进行初始化的时候,会在其构造函数内部第一行自动添加super(),运行父类的构造函数。

 
class Fu
{
Fu()
{
System.out.println("fu");
}
}

class Zi extends Fu
{
Zi()
{
System.out.println("zi run");
}
}

class ExtendsDemo4
{
public static void main(String[] args)
{
Zi z = new Zi();
}
}

默认添加的super()会访问父类中空参数的构造函数。而子类中所有的构造函数默认调用的都是没有参数的那个父类构造函数。

为什么子类一定要访问父类中的构造函数?
因为子类要获取父类中的各种数据,所以子类对象在建立时,需要先查看父i类是如何对这些成员进行初始化的,因此需要调用父类的构造函数。

如果想指定其它有参数的父类构造函数,可以通过super制定。

注意:super一定要在子类构造函数的第一行。

子类实例化过程 结论:
子类的所有构造函数,默认都会访问父类中的空参数构造函数。因为隐式super()

当父类中没有空参数构造函数的时候,子类必须通过super指定构造函数。

当然,子类的构造函数也可以使用this来访问本类构造函数。无论如何,子类中至少会有一个构造函数会访问父类的构造函数。

-----------------------------------------------------------------------------------------------------------------
FINAL 关键字

final:最终。是一个修饰符。
特点:
1.可以修饰类、变量、函数。
2.被final修饰的类不可以被继承。
3.被final修饰的成员函数不可以被复写。
4.被final修饰的变量是一个常量,只能赋值一次,既可以修饰成员变量也可以修饰局部变量。
5.内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。(前四点要记住。

当描述事物的时候,一些数据出现之后值就不应该被改变,那么这时为了增强阅读性,会用final修饰,提示用户该数据不可以被改变。类似于c++中的const。

常量的书写习惯是,全部大写,单词之间通过_下划线进行连接。
凡是final,被复写时就会编译出错。
出险原因:继承打破了封装。·final可以避免类被继承,也可以避免被复写。

-----------------------------------------------------------------------------------------------------------------

抽象类

class BaseStudent
{
void study()
{
System.out.println("study");
}
}

class AdvStudent
{
void study()
{
System.out.println("study");
}
}

class AbstractDemo
{
public static void main(String[] args)
{
System.out.println("hello world");
}
}


当我们需要同样功能、不同内容的成员函数的时候,可以进行向上抽取。
这时,只抽取功能定义,不抽取功能主体。

这样抽取出来的东西,因为不具有方法体而不知道其具体的功能,所以是‘抽象’的,用abstract修饰。

抽象类的特点:
1.抽象方法一定定义在抽象类中。
2.抽象方法和抽象类都必须被abstract关键字修饰。
3.抽象类不可以用new创建对象。因为有些方法没有被具体实现。
4.抽象类中的方法要被使用,必须由子类复写完所有的抽象方法之后,建立子类对象调用。
如果子类只覆盖了部分抽象方法,则该子类依旧是一个抽象类。

抽象类和普通类的区别:
抽象类比一般类多了抽象方法(函数)。就是在类中可以定义抽象方法。
抽象类不可以实例化。


抽象类和普通类没有太大的不同,该如何设计还是如何设计。
只不过,抽象类中出现了一些尚不能 确定的功能(抽象方法),需要由子类去实现。

注意:抽象类中可以没有抽象方法。这样做仅仅是不让该类建立对象。(java中真有这样的方法。)
----------------------------------------------------------------------------------------------------------------

加入我们开发一个系统时需要对员工进行建模。
员工含有:姓名 工号 工资

经理也是员工。经理除了员工属性之外,还有奖金的属性。

用继承思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。

员工类:name id pay
经理类:继承了员工,有bonus

class Employee
{
private String name;
private String id;
private double pay;
Employee(String name,String id,double pay)
{
this.name = name;
this.id = id;
this.pay = pay;
}

public abstract void work();//抽象类留空
}

class Manager extends Employee
{
private int bonus;
Manager(String name,String id,double pay,int bonus)
{
super(name,id,pay);
this.bonus = bonus;
}
public void work()
{
System.out.println("manager work");
}
}

class Pro extends Employee
{
pro(String name ,String id,int pay)
{
super(name,id,pay);
}

public void work()
{
System.out.println("pro work");
}
}

-------------------------------------------------------------------------------------------------------------------
需求:获取一段程序运行的时间。

原理:获取开始时间和结束时间。

需求一个类:system中的currentTimeMillis

class GetTime
{
public void getTime()
{
long start = System.currentTimeMillis();

for(int x = 0; x < 1000   ; x ++)
{
System.out.print("x");
}
long end = System.currentTimeMillis();

System.out.println("毫秒"+(end - start));
}
}
class TemplateDemo
{
public static void main(String[] args)
{

GetTime gt = new GetTime();
gt.getTime();
System.out.println("hello world ");
}
}

设计思想:把需要的代码设计成一个函数,并变成抽象类。实现时先复写需要运行部分的函数,然后在计时区记录时间。

abstract class GetTime
{
public final void getTime ()
{
long start =    System.currentTimeMillis();
runcode();
long end =    System.currentTimeMillis();
}

public abstract void runcode();
}

当代码完成优化后,可以解决一类问题了。
这种方式,我们叫做 模板方法设计模式。

什么是模板方法?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分需要依赖不确定的部分存在。

此时,将不确定的部分暴露出去,由该类的子类去完成。
-------------------------------------------------------------------------------------------------------------------
接口

格式:

interface{}

接口中的成员修饰符是固定的。
成员变量:public static final
成员函数:public abstract
接口的出现,意味着多继承的另一种表达方式,即 多实现。

抽象类中可以有抽象方法也可以有非抽象方法。

如果一个抽象类中所有的方法都是抽象方法,那么可以理解为 是一个接口。(一种方便理解的说法。)

接口跟类表现方式差不多,但是换了个关键字。

interface{
public static final int NUM = 3;
public abstract void show();
}

接口定义的时候,格式特点:
1.接口中常见定义:常量,抽象方法。
2.接口中的成员都有固定修饰符:
常量:public static final
方法:public abstract(接口中所有的成员都是public的。

只要放在interface里,就会被自动补齐相应修饰符。当然,为了方便程序阅读,尽量把所有的修饰符都写完整。

新关键字:对于抽象类,我们使用继承(extends)。对于接口,我们使用实现。(implement)

接口:是不可以创建对象的,因为有抽象方法未被实现。

interface Inter
{
public static final int NUM = 3;
public abstract void show();
}

class Test implements Inter
{
  public void show(){};
}

class InterfaceDemo
{
public static void main(String[] args)
{
Test t = new Test();

System.out.println(t.NUM);//对象调用成员
System.out.println(Test.NUM);//类调用成员
System.out.println(Inter.NUM);//interface编译之后也会生成一个class文件
}
}

然而并不能进行赋值。

接口可以被类多实现。也就是说,一个类可以同时实现多个接口。这是java支持多继承的一种体现方式。

为什么接口可以避免冲突?
多继承有方法体,而多实现不会有冲突的方法体。

一个类,在继承一个类的同时,还可以实现别的接口。
接口与接口之间可以继承。
---------------------------------------------------------------------------------------------------------------
接口的特点
接口是对外暴露的规则
接口是程序的功能拓展
接口可以用来多实现
类与接口之间是实现关系,而且类可以集成一个人类的同时实现多个接口
接口与接口之间可以继承。

降低了耦合性。(你没做完,我就不能动),增加了开发效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值