黑马程序员-类与类之间的关系

------- android培训java培训、期待与您交流! ----------

类与类有哪些关系呢?

第一种:继承

1.什么是继承

每个事物都可以是一个类,那么类与类之间也是有公共部分的,把这些的公共部分提取出来单独描述的类,被称为父类

比如:服务员和顾客都可以作为单独的一个类来描述,他们的公共部分就是都属于人,那么人中的方法就是服务员和顾客中抽取出来的公共部分。

这样就可以直接让服务员和顾客都继承这个类,就可以使用这些公共方法而不用再重新定义一遍,提高复用性。

2.继承的好处

提高复用性,使类与类之间产生关系。

3.弊端:java只支持单继承,因为如果一个类有两个父类,而那两个父类又有相同的功能,那么子类就不知道该调用哪个。

所以,一个类最多只能继承一个类。但是可以有多重继承,即儿子有老子,老子有老子这样的形式,隐式的就代表了儿子继承老子的老子

4.由上面的特性不难归纳出继承的特点

父类是子类共同抽取的部分,所以一个体系要想被使用,就可以直接去看父类的用法,这样可以最快的了解这个体系的基本功能

而如果要建立对象的话,使用最子类对象最好,因为最子类对象不仅可以使用父类中的功能,还可以使用子类自己的特有功能

5.继承方式

关键字extends

使用方法: class Student extends Person 

让Student类继承Person类,就可以使用Person内部的成员了。

如果Person内部的成员在Student类中又重复定义过,那么怎么使用父类的呢?

使用关键字super


this和super的比较

this代表的是本类中的引用对象

super代表的是子类所述父类的实体引用


因为类与类之间产生了关系,所以他们也就有了复写这个特性。

当子父类中出现了一模一样的方法时,建立子类对象会运行子类中的方法,这时,如果父类中也有同样的方法,就称为复写

好比老子有100W,他的实现是慈善,而我从他那里继承了这些钱后我想干的事情就不是慈善了而是做别的事情。这就是复写了老子的方法。


子类的构造函数初始化

子类在初始化构造函数时,都会自动的加入一条隐身的语句suepr()用来运行父类的构造函数。

因为子类继承的父类的函数,就必须知道父类到底是怎样定义这些成员的。

如果父类中没有空参数的构造,就要在子类手动指定一个父类初始化构造函数。

可以使用super(参数)来表示父类的构造函数


问题1: super和this能不能同时出现在构造中

不能,因为这两个语句都只能定义在第一行

问题2: 为什么一定要定义在第一行

  因为super()或者this()都是调用构造函数,用于初始化,所以必须先完成


继承的简单判断

判断两个类的所属关系,当继承后,被继承的类的功能,子类是全部都具备的。如果不是,不可以继承


复写的注意事项

子类覆盖父类的方法时,必须保证,子类方法的权限大于父类方法的权限。

覆盖时,要么全静态,要么都不静态。


复写的弊端:打破封装,如何不让其被复写被继承


关键字final

1.修饰符,修饰类,方法,变量

2.特点:

被修饰的类不能被继承

被修饰的方法不能被复写

被修饰的变量不能修改值,即作为常量

所以由final修饰的变量的书写方法:全部大写,字母与字母间使用_


既然有不想被继承的方式,那么就一定会有相对的想被继承的方式

关键字 abstract

被abstract修饰的类都是抽象类,不能创建对象

必须将其抽象类的抽象方法全部实现后才可以创建对象


抽象类的特点

有抽象方法的类绝对是抽象类,必须使用abstract修饰

抽象方法只定义方法声明,不实现,即不写花括号

抽象类不可以被创建

只能继承后复写所有抽象方法后才可以创建对象


抽象类与其他类的区别

仅仅在于多了一些抽象方法而已,其他都是没区别的。

由于这些抽象方法,所以不能创建本类对象


抽象关键字与哪些是不共存的? final,private,static


由此引申出来的设计模式: 模板方法设计模式

模板方法设计模式:当成员函数的内容一部分被实现,而另一部分不确定时,可以将此不确定的部分提取出来,让子类去实现

即单独把这部分内容使用abstract定义


abstract class Person

{

public final void do() 

{

System.out.println("工作了!");

work(); //做什么工作并不清楚,所以将其提取出来定义成抽象,由继承他的子类来确定内容

//这种思想就是模板设计模式,父类作为一个模板,让子类来实现。

}

public abstract void work();

}

class Waiter extends Person

{

public void work()

{

System.out.println("服务顾客");

}

}


第二种实现形式:接口

由于继承的局限性,只能单继承,所以产生了接口这个概念,关键字interface,用来定义接口

接口中的成员:

属性:全局常量。 public static final

方法:抽象方法。 public abstract

无需自己手动添加修饰符,都有固定的修饰符


接口中因为有抽象,所以不可以被实例化,接口的子类必须实现了接口中的所有抽象才可以实例化

否则还是一个抽象类


子类如何去实现接口: 通过implements关键字

与继承不同的是接口是可以多实现的,这样可以对代码进行扩展。有更高的完成度


接口是用于设计上,设计上的特点:

接口是对外提供的规则

接口是功能的扩展

接口降低了耦合性


抽象类更多的是将共性内容抽取出来,而接口比它更全面,因为内部全部都是抽象方法,是对对象的一个扩展。

但是都是不停抽取出来的结果


继承和接口的区别

1.抽象类只能被继承,而且只能单继承

    接口需要被实现,而且可以多实现

2.抽象类中可以定义非抽象方法,子类可以直接继承使用

    接口中都有抽象方法,需要子类去实现

3.抽象类使用的是is a 关系

    接口使用的是like a 关系

也说明了一个是单继承 一个是多实现

4.抽象类的成员修饰符可以自定义

接口中的成员修饰符是固定的,全都是public的



由此两种方式继承和接口而出现的一种体现形式:多态

体现:父类引用或者接口的引用指向了自己的子类对象  

多态的好处:再一次的提高了程序的扩展性

多态的弊端:当父类引用指向了子类对象时,虽然提高了扩展性,但是只能访问父类中具备的方法。不可以访问特有方法

多态的前提:必须要有关系! 继承或者实现

通常会有覆盖操作


多态的三个规律  这个是多态最重要的地方。要反复练习。

使用了多态时,每个阶段参考的依据都不一样。

成员变量:如果子类和父类的变量同名

编译时期,看父类引用或者接口引用所属的类是否有调用的成员,如果没有该成员,则编译失败

运行时期,依旧看父类引用或接口引用是否有调用的成员。


成员函数:如果有同名的成员函数

编译时期:看父类引用或者接口引用所属的类是否有调用的成员,如果没有,则编译失败

运行时期:看实例对象是否有是否有调用的方法。

因为复写,子类可以复写父类的方法。只要父类有此调用成员,而子类也有复写过,那么就会调用子类的


静态函数:如果同名

编译时期:看父类引用或者接口引用所属的类是否有调用的成员,如果没有,则编译失败

运行时期:看父类引用或者接口引用所属的类是否有调用的成员,如果没有,则编译失败

因为static修饰的函数是在对象创建之前调用的,所以只需看引用即可


想用子类的特有方法,就要判断对象是哪个具体的子类类型

instanceof关键字:判断对象是否实现了指定的接口或者继承了指定的类


格式 对象 istanceof 类型   返回一个boolean值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值