首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

黑马软件工程师-抽象类和接口

2013-02-24 
黑马程序员--抽象类和接口 ------- android培训、java培训、期待与您交流! ----------?抽象类包含了抽象方法

黑马程序员--抽象类和接口




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

?

抽象类


包含了抽象方法的一个类叫作“抽象类”。如果一个类里包含了一个或多个抽象方法,类就必须指定成

abstract(抽象)。“抽象方法”,属于一种不完整的方法,只含有一个声明,没有方法主体。


下面是抽象方法声明时采用的语法:

abstract void f();


如果从一个抽象类继承,而且想生成新类型的一个对象,就必须为基础类中的所有抽象方法提供方法定义。

如果不这样做(完全可以选择不做),则衍生类也会是抽象的,而且编译器会强迫我们用abstract 关键字标志那个类的“抽象”本质。

即使不包括任何abstract 方法,亦可将一个类声明成“抽象类”。如果一个类没必要拥有任何抽象方法,而且我们想禁止那个类的所有实例,这种能力就会显得非常有用。



在面向对象领域,抽象类主要用来进行类型隐藏。我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。熟悉OCP的读者一定知道,为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。


(1)多个类有相同的方法声明,但是方法体不一样。这个时候,我们考虑把方法声明进行抽取。

? 让子类继承后,自己去实现方法体。没有方法体的方法,我们需要用抽象标志下。

? 抽象的关键字是:abstract。

(2)抽象类:

该方法称为抽象方法,包含抽象方法的类就是抽象类。

(3)抽象类的特点:

A:抽象类和抽象方法都要用abstract进行修饰

B:抽象类不能被实例化

C:抽象类中不一定有抽象方法,但是,有抽象方法的类一定是抽象类。

(4)抽象类中数据的特点

A:成员变量

抽象类中可以有变量,也可以有常量。

B:成员方法

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

C:构造方法

抽象类是一个类,所以,它有构造方法。

虽然本身不能实例化。但是可以给子类实例化使用。

(5)抽象类中的问题

A:抽象类中是否有构造方法?能不能被实例化?如果不能,为什么有构造方法?

抽象类有构造方法。

????????


1. 抽象方法 abstract void f(); 抽象方法不能包含有任何方法的BODY 。

2. 如果一个类包含1个或者多个抽象类, 则该类必须限定为抽象的。

需要在前面指定 abastract 关键字。

(1)抽象类不能被实例化

(2)包含抽象方法的类,必须标识 abstract

3. 如果从一个抽象类继承, 必须对所有抽象方法进行覆盖 , 否则导出类也是抽象的

4. 也可以考虑创建没有任何抽象方法的抽象类 。



abstract class Instrument {

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

private int i; // Storage allocated for each

public abstract void play(Note n);

public String what() { return "Instrument"; }

public abstract void adjust();

}




抽象类不能被实例化。

抽象类中的构造方法供子类实例化调用。

B:抽象关键字abstract不可以和哪些关键字共存?

**private:

私有内容子类继承不到,所以,不能重写。

但是abstract修饰的方法,要求被重写。两者冲突。

????????

抽象类的特点:

1.抽象方法一定定义在抽象类中

2.抽象方法和抽象类都必须被abstract关键字修饰

3.抽象类不可以用new创建对象,因为调用抽象方法没有意义

4.抽象类中的抽象方法要被使用,必须由子类复写其所有的抽象方法后,建立子类对象调用

如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类


抽象类和一般类没有太大的不同

只是要注意该怎么描述事物就怎么描述,只不过该事物中出现了一些看不懂的东西

这些不确定的部分也是该事物的功能,需要明确出来,但是无法定义主体


抽象类比一般类多了个抽象函数

抽象类不可以实例化


特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象

*/

abstract class Student

{

abstract void study();//抽象方法必须存储在抽象类中

void sleep()//抽象类也可以有一般方法,也可以有抽象方法

{

System.out.println("躺着");

}

}


class ChongCiStudent extends Student

{

void study()

{

System.out.println("chongci");//子类要复写父类所有的抽象方法

}

}

class BaseStudent extends Student

{

void study()

{

System.out.println("base study");

}

}

class AdvStudent extends Student

{

void study()

{

System.out.println("adv? study");

}

}


class? AbstractDemo

{

public static void main(String[] args)

{

System.out.println("Hello World!");

}

}




接口interface



(1)当一个类中的方法都是抽象的时候,java提供了另一种表示方式,叫接口。

? 用interface关键字表示。类与接口关系用implements表示。

(2)接口的成员特点

A:成员变量

是常量,默认修饰 public static final

B:成员方法

都是抽象的,默认修饰 public abstract

(3)关系

A:类与类的关系

是继承关系。类与类只能单继承,可以多重继承。

B:类和接口的关系

是实现关系。类可以多实现接口。

类在继承一个类的同时,可以实现多个接口。

C:接口和接口的关系

是继承关系。接口可以多继承接口。

(4)接口的特点

A:是对外暴露的规则

B:是功能的扩展

C:接口的出现降低耦合性。

耦合(类与类之间的关系)

内聚(类完成功能的能力)

编程规范:低耦合,高内聚。

D:接口可以多实现。如:CPU和主板、笔记本的USB插口、插座

(5)接口和抽象类的区别

A:抽象类只能被单继承

? 接口可以多实现,接口的出现避免了多继承的局限性。

B:抽象类中的数据特点:

成员变量:可以是变量,也可以是常量

成员方法:可以是抽象方法,也可以是非抽象方法

构造方法:有构造方法

? 接口中的数据特点:

成员变量:是常量。默认修饰 public static final

成员方法:都是抽象方法。都有默认修饰 public abstract

构造方法:没有构造方法

C:抽象类中定义的是继承体系中的共性功能。

? 接口中定义的是继承体系中的扩展功能。

D:抽象类被继承是"is a"关系:xx是yy的一种

? 接口被实现是"like a"关系:xx像yy的一种

04 子父类中变量的特点

内存中的方法区(静态区 非晶态区)

多态:父类super指向子类对象


05

子父类中函数的特点

覆盖(重写):子父类中同名函数

当子类出现和父类一样的函数时

当子类对象调用该函数,会运行子类函数的内容

如同父类的函数被覆盖一样


重写(覆盖)


当子类集成了父类,沿袭了父类的功能到子类中

但是子类虽有该功能,但是功能的内容却和父类不一致

这时,没必要定义新功能(speak2的出现没有意义),而是使用覆盖特殊,保留父类的功能定义并重写功能内容

class Tel

{

void show()

{

System.out.println("number");

}

}


class NewTel extends Tel

{

supper.show();//System.out.println("number");

System.out.println("name");

System.out.println("pic");

}


覆盖:

1,子类覆盖父类,必须保证子类权限大与父类权限才可以覆盖

2.静态只能覆盖静态


权限:public >默认> private



重载:只看同名函数的参数列表

重写:字父类方法要一模一样


06子类实例化过程

在对子类对象进行初始化时,父类的构造函数也会运行

那是因为子类的构造函数默认第一行有一条隐式的语句supper();

supper();会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是supper();


class Zi extends Fu

{


Zi()

{

//supper();隐式说明

//super(4); 手动访问

System.out.println("zi run");

}

??????? Zi(int x)

??????? {

???????????? //super();

??????????? System.out.println("zi..."+x);

??????? }

为什么子类一定要访问父类中的构造函数?

因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的

所以子类对象初始化时,要先访问一下父类中的构造函数

如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来完成


class Person

{

String name;

Person(String name)

{

this.name = name;

}

void show(){}

}


class Student extends Person

{

Student (String name)

{

super(name);

}

void method()

{

super.show();

}

}

super语句一定定义在子类构造函数的第一行


Zi(int x)

{

//this();有this就不能用supper访问父类了

//super(2);

System.out.println("zi...."+x);

}

}


子类的实例化过程

结论:子类的所有构造函数,默认都会访问父类中空参数的构造函数,因为每一个构造函数内第一行都有一句隐式的super语句


当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问的构造函数


子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数,子类中至少会有一个构造函数访问父类中的构造函数

this和super不能在同一行



final关键字

final:最终,作为一个修饰符

1,可以修饰类:函数,变量

2.被final修饰的类不可以被继承.为了避免被继承,被子类复写功能

3.被final修饰的方法不可以被复写

4.被final修饰的变量是一个常量,只能赋值一次,既可以修饰成员变量又可以修饰局部变量


??? 当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读,都给这些值起个名字方便阅读

??? 而这个值不需要改变,所以给这些值加final修饰(类似于宏定义)

??? 作为常量:常量的书写规范所有字母都大写,如果有多个单词组成

??? 单词见通过_连接(JAVA_HOME)。

5.内部类定义在类中局部位置上时,只能访问该局部被final修饰的局部变量(类的修饰符有public,final)或默认


全局常量:

public static final double PI = 3.14; 类名直接访问

?

热点排行