黑马程序员_Java基础_面向对象(三)_07

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

导读:继承概述,聚集关系,子父类中变量关系,
子父类中函数覆盖,子父类中构造函数,final关键字,抽象类,
  模板方式设计模式,接口,接口特点

1、继承概述

l  面向对象的第二种特征:继承

Ø  类本身就是一种抽象的行为。父类的由来是由子类抽取而来的。

Ø  :人—学生工人

Ø 将学生和工人的共性描述提取出来,单独进行描述,只要让学生和工人与单独描述的这个类有关系,就可以了。

Ø  Studentperson的子类。Person就是Student这个类的父类。Person也叫做基类或者超类

l  继承:

1)提高了代码的复用性。

2)让类与类之间产生了关系。有了这个关系,才有了多态的特性。

注意:

千万不要为了获取其他类的功能,简化代码而继承。必须是类与类之间有所属关系才可以继承。所属关系是谁是谁中的一种(is a)。

l  怎样判断两个类中有没有关系?

可在继承一下,看看父类中的内容是不是子类中都应该具备的。如果父类中有的功能不是子类应该具备的,则不应该继承。

l  Java语言中:java只支持单继承,不支持多继承。因为我继承容易带来安全隐患。因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪一个。但是java保留这种机制。并用另一种体现形式来完成表示(多实现)。

l  java支持多层继承。也就是一个继承体系(C继承自BB继承自AC是孙子,B是父亲,A是爷爷)

l  如何使用一个继承体系中的功能呢?

Ø  想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。通过了解共性功能,就可以知道该体系的基本功能。那么这个体系已经可以基本使用了。

Ø  为什么在具体调用时,要创建最子类的对象呢?

一是因为有可能父类不能创建对象(抽像类和接口),二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。

Ø  简单一句话:查阅父类功能,创建子类对象使用功能。

 

2、聚集关系

l  类与类之间,对象和对象之间,事物和事物只间不仅只有继承这一种。还有组合关系。

l  聚集,即谁里边有谁(has a),它又分为聚合和组合。它们的紧密联系程度稍有不同。

Ø  聚合:球队—球员  球员是球队中的一员。

Ø  组合:事物的联系更紧密。手和身体。手是身体必不可少的一部分。

 

3、子父类中的关系变量

l  如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this。子类要访问父类中的同名变量,用supersuper的使用和this的使用几乎一致。this代表的是本类对象的引用。super代表的是父类对象的引用。

class Fu

{

       private int num = 4;

}

class Zi extendsFu

{

       void show()

       {

              System.out.println(this.num);//this.numsuper.num打印出来的都是4,可以有两种现解方式。第一:Zi继承自Fu所以子中也有一个num。第二:thissuper指向同一个对象(对象中有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

 

6final关键字

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可以直接继承自ABinterface 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培训 、期待与您交流! ----------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值