Java基础学习笔记6

来源:互联网 发布:ipad无法加入wifi网络 编辑:程序博客网 时间:2024/05/20 08:21

补充:黑马程序员教程

包(package)

作用:

对类文件进行分类管理;

给类提供多层命名空间;

写在程序文件的第一行;

类名的全称是     包名,类名;

包也是一种封装形式。

包详见P87(4.8包)



第七章 面向对象设计的基本原则

7.1 UML(统一建模语言)类图简介

UML类图属于结构图,常被用于描述一个系统的静态结构。

一个UML图包含有类的UML图,接口的UML图,以及泛花关系的UML图,关联关系的UML图,依赖关系的UML图和实现关系的UML图。

7.1.1 类的UML图

在类UML图中,使用一个长方形描述一个类的主要构成,将长方形垂直的分为三层。

顶部第一层是名字层,如果类的名字是常规字,表明该类是具体类;如果类的名字是斜体字形,则表示抽象类。

第二层是变量层,也称属性层。列出类的成员变量及类型,格式是“变量名字:类型”。如果变量的访问权限是public ,需要在变量的名字前面用“+”符号修饰;如果变量的访问权限是protected,需要在变量的名字前面用“#”符号修饰;如果变量的访问权限是private,需要在变量名字前面用“-”符号修饰;如果变量访问的权限是友好的,变量名字前不需要使用任何符号修饰。


第3层是方法层,也称操作层,列出类的方法及返回类型,格式是“方法名字(参数列表):类型”,如果变量的访问权限是public ,需要在变量的名字前面用“+”符号修饰;如果变量的访问权限是protected,需要在变量的名字前面用“#”符号修饰;如果变量的访问权限是private,需要在变量名字前面用“-”符号修饰;如果变量访问的权限是友好的,变量名字前不需要使用任何符号修饰。




7.1.2表示接口的UML图

和表示类的UML图类似,也分为三层。

顶部第一层是名字层,接口的名字必须是斜体字,而且需要用《interface》修饰名字,并且该修饰和名字分列在两行。

第二层是常量层,列出接口中的常量及类型,格式是:“常量名字:类型”。在java中常量的访问权限都是public,所以需要在常量名字前面用“+”符号修饰。

第3层是方法层,也称操作层,列出类的方法及返回类型,格式是“方法名字(参数列表):类型”,在java中方法的访问权限都是public,所以需要在常量名字前面用“+”符号修饰。


7.1.3泛化关系

对于面向对象语言,UML中所说的泛化关系就是继承关系。如果一个类是另一个类的子类,那么UML通过一个实线连接连接两个类的UML图来表示二者之间的继承关系,实线的始端是子类的UML图,终端是父类的UML图,但终端要使用一个空心的三角形表示实线的结束。


7.1.4 关联关系

如果A类的成员变量时用B类的变量(接口)来声明的变量,那么成A和B的关系是关联关系,称A关联于B。如果A关联于B,那么UML使用一个实线连接A和B的UML图,实线的始端是A的UML图,终端是B的UML图,但终点端使用一个指向B的箭头表示实线的结束。


7.1.5  依赖关系

如果A类中某个方法的参数用B类(接口)来声明的变量或者某个方法返回的数据类型是B型的,那么A和B的关系是依赖关系,称A依赖于B。如果A依赖于B,那么UML使用一个虚线连接A和B的UML图,虚线的始端是A的UML图,终端是B的UML图,但终点端使用一个指向B的箭头表示虚线的结束。


7.1.6 实现关系

如果一个类实现了一个接口,那么类和接口的关系是实现关系,称类实现接口。连接方式类似于以上几种,用虚线连接。


7.1.7  注释

UML在一个带卷角的长方形中显示给出的注释,并用虚线将这个带卷角的长方形和它所注释的实体连接起来。





7.2 面向抽象原则

7.2.1抽象类和接口

1,抽象类

抽象类具有以下特点:

(1)抽象类中可以有abstract方法,也可以由非abstrsct方法;

(2)抽象类不能用new运算符创建对象;

(3)如果一个非抽象类是某个抽象类的子类,那么它必须重写父类的abstract方法;

(4)做上转型对象:尽管抽象类不能用new创建对象,但它的非abstract子类必须要重写它的所有abstract方法,这样一来。就可以让抽象类声明的对象成为其子类对象的上转型对象,并调用子类重写的方法。例如:

/*下列抽象类A中有一个abstract方法add(int x,int y):*///A.javapublic abstract class A{public abstract int add(int x.int y);}/*下列B是A的一个非abstract类,子类B在重写父类A中的abstract方法时add(int x,int y)时,将其实现为计算x与y的值*/public class B entends A{public int add(int x,int y){return x+y;}/*假设b是子类B创建的对象,那么可以让A类声明的对象a成为对象b的上转型对象,即让a存放b的引用。上转型对象调用子类重写的add()方法,例如:*/public class Application{public static void main(String args[]){A a;a=new B();//a是B 类对象的上转型对象int m=a.add(3,2);System.out.println(m);}}}


2.接口

接口(Interface)的特点:

(1)接口中只可以有public权限的abstract方法,不能有非abstract方法;

(2)接口由类去实现,即一个类如果实现一个接口,那么它必须重写接口中的abstract方法;

(3)接口回调:

接口回调指把实现接口的类的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类重写的接口方法。

Com.java   //Com中有一个abstract方法sub(int x,int y);

public interface Com{

public abstract int sub(int x,int y);

}

ComImp.java   //ComImp是实现接口的类,ComImp类在重写Com接口中的abstract方法                                       sub(int x,int y)时,将其实现为计算x与y的差

class ComImp implements Com{

public int sub(int x,int y){

return x-y;

}

可以让Com接口声明的接口变量com存放ComImp类的对象的引用,那么com就可以调用ComImp类实现的接口中的方法。例如:

Application.java

public static void main(String args[]){

Com com;

com=new ComImp();  //com变量存放ComImp类的对象的引用

int m=com.sub(8,2);   //com回调ComImp类实现的接口方法

System.out.println(m);  //输出结果为6

}

}




7.22面向抽象


所谓面向抽象,是指当设计一个类时,不让该类面向具体的类,而是面向抽象类或接口,即所设计类中的重要数据是抽象类或接口声明的变量,而不是具体类声明的变量。

例如:

已经有一个Circle类,该类创建的对象circle调用getArea的方法可以计算圆的面积。代码如下:

Circle.java

public class Circle{

double r;

Circle(double r){

this.r=r;

}

public double getArea(){

return(3.14*r*r);

}

}

现在要设计一个pillar类(柱类),该类的对象调用用getVolume()方法可以计算柱体的体积。代码如下:

Pillar.java

public class Pillar{

Circle bottom;//将Circle对象作为成员,bottom是用具体类Circle声明的变量

double height;

Pillar(Circle bottom,double height){

this bottom=bottom;this height=height;

}

public double getVolume(){

retirn bottom.getArea()*height;

}

}

应用面向抽象的思想,我们在设计程序的时候,不应该关心底是什么形状的具体图形,而是应该考虑计算体积中关键的求面积的方法,下面是用面向抽象的思想重写Pillar了类:

首先定义一个抽象类Geometry(或接口),该抽象类中定义了一个抽象的getArea()方法。Geometry类如下:

Geometry.java

public abstract class Geometry{ //如果使用接口则用interface来定义Geometry;

public abstract doublle getArea();

}


现在我们就可以面向Geometry类编写代码,以下的Pillar类的设计将不依赖于具体类,而是面向Geometry类,即pillar类中bottom是用抽象类Geometry声明的变量,而不是具体类声明的对象。代码如下:
Pillar.java
Geometry bottom;
double height;
pillar(Geometry bottom,double height){
this.bottom=bottom;this.height=height;
}
public double getVolume(){
return bottom.getArea()*height;//bottom可以调用子类重写的getAraea方法
}

下列Circle和Rectangle类都是Geometry的子类,二者必须重写Geometry类的方法getArea()来计算各自得面积。
Circle.java
public class Circle extends Geometry{
double r;
Circle(double r){
this.r=r;
}
public double getArea(){
return(3.14*r*r);
}
}

Rectangle.java
public class Rectangle extends Geometry{
double a,b;
Rectangle(double a,double b,double c){
this a=a;this b=b;
}
public double getArea(){
return a*b;
}
}
下列Application就可以用Pillarlei类创建出具有矩形底或者圆形底的柱体了:
public class Application {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
Pillar pillar;
Geometry bottom;
bottom=new Rectangle(12.0,22.0,100.0);
pillar=new Pillar(bottom,58);
System.out.println("矩形底的柱体的体积"+pillar.getVolume());
bottom=new Circle(10);
pillar=new Pillar(bottom,58);
System.out.println("圆形底的柱体体积"+pillar.getVolume());
 }
}


7.3开闭原则

“开闭原则”,就是让用户的设计应当对扩展开放,对修改关闭。本质是指当在一个设计中增加新的模块时,不需要修改现有的模块。

优点:程序易维护


注意:在程序设计好后,首先对abstract类的修改关闭,否则,一旦修改abstract类,即将导致它的所有子类都需要进行修改,应当增加对abstract的子类的开放,即在增加新的子类时,不需要修改其他面向抽象类而设计的重要类。



7.4 多用组合,少用继承原则

1,继承与复用

子类继承父类的方法作为自己的一个方法,也就是说,父类的方法被子类以复用的方式复用。

优点:

子类可以重写父类的方法,即易于修改或扩展那些被复用的方法。

缺点:

(1)子类从父类继承的方法在编译时刻就确认下来了,所以无法在运行期间修改从父类继承的方法的行为。

(2)子类和父类的关系是强耦合的关系,当父类的方法的行为更改时,必然导致子类发生变化。

(3)通过继承进行复用也称“白盒”复用,其缺点是父类的内部细节对于子类而言是可见的。



2组合与复用

我们已经知道,一个类的成员变量可以是java允许的任何数据类型,因此,一个类可以把对象作为自己的成员变量,如果用这样的类创建对象,那么该对象中就会有其他对象。也就是说,该对象将其他对象作为自己的组成部分。或者说,该对象由几个对象组合而成的。

如果一个对象a组合了对象b,那么对象a就可以委托对象b调用其他方法,即对象a以组合的方式复用对象b的方法。

通过组合对象来复用方法的优点如下:

(1)通过组合复用方法也称“黑盒”复用,因为当前对象只能委托所包含的对象调用其方法,当前对象所包含的对象的方法的细节对当前对象是不可见的。

(2)对象与所包含的对象属于弱耦合关系,因为如果修改当前对象所包含的对象的类的代码,不必修改当前对象的类的代码。

(3)当前对象可以在运行时刻动态的指定所包含的对象。


通过组合对象来复用方法的缺点如下:

(1)容易导致系统中放入对象过多;

(2)为了能组合多个对象,必须仔细的对接口进行定义;


3,组合与继承

尽量要使系统类之间是低耦合的,而不是强耦合。方法则希望是高内聚的,因为高内聚便于类的维护。




0 0
原创粉丝点击