目录
3.3 类的属性(Attribute)
3.3.1 可见性(Visibility)
3.3.2 属性的名称
3.3.3 数据类型
3.3.4 初始值
3.3.5 属性字符串
3.4 类的操作(Operations)
3.4.1 参数表
3.4.2 返回类型
3.5 类的职责和约束
4.接口(interface)
(接上一章节)
【UML】第9篇 类图-CSDN博客
3.3 类的属性(Attribute)
类的属性用于描述类的一个特征,这个特征是类的每个实例所共有的。一个类可以有零到多个属性。类的属性定义语法如下:
[可见性] 属性名称 [:数据类型] [=初始值] [{属性字符串}]
上面的语法中,[]中的内容表示是可选的。可见性默认是私有,属性名称是必要的,其他都可以省略。
下面对以上语法中的各个部分,进行说明:
3.3.1 可见性(Visibility)
可见性用于控制该属性被类的外部成员的可访问性。主要有以下四种情况:
+:公有属性(Public),其它类可以访问该属性;
-:私有属性(Private),不能被其它类访问(默认为私有);
#:保护属性(Protected),只能被本类及其派生类访问;
3.3.2 属性的名称
能够准确描述类特征的一个标识符,属性名通常是一个名词或名词短语。一般单字属性使用小写字母,多字属性从第2个单词开始,每个单词的第一个字符要大写。也就是我们说的驼峰命名方法。
很多人对驼峰命名法,有不同的表述,其实,有2种驼峰命名法。
- 小驼峰法(lower camel case):第一个单词以小写字母开始;第二个单词的首字母大写,例如:myFirstName、myLastName。这种命名方式在Java中较为常见。
- 大驼峰法(Upper Camel Case):每一个单词的首字母都采用大写字母,例如:ClassName、MyName。这种命名方式在C#中较为常见。
在这里,属性的命名,一般使用小驼峰法。
3.3.3 数据类型
属性所属的数据类型,如整型、浮点型、字符型,也可以是用户自定义的类型。例如上图中的String,int。
3.3.4 初始值
属性的默认值,在类的实例没有赋其它值时,将采用该值作为该属性的值。例如上图中的xiaobai,就是初始值。
3.3.5 属性字符串
用来指定该属性的其它信息。任何希望进一步描述该属性又没有合适的地方时都可以放在此处。
3.4 类的操作(Operations)
操作是类的方法或行为,描述了类可以对其属性执行的操作或计算。
在UML中,操作列在类图的第三部分,位于属性之后,并在花括号内。操作的表示包括可见性、名称、参数和返回类型。
类图的表达中,可以只有属性,也可以只有操作,也可以都有。
类的操作定义的语法是:
[可见性] 操作名称 [(参数表)][:返回类型][{属性字符串}]
类的操作的可见性,和熟悉的可见性相同,也是共有、私有和受保护三种。
操作的名称,也是小驼峰命名方法。
注意:如果是操作,没有参数,也要有()标记。
3.4.1 参数表
如上图,-eat(food:Food):String操作,有一个参数食物,属于Food类。如果有多个参数,用“,”隔开。
注意,方法如果要表明返回值,需要在参数的括号后面,加上冒号“:”和返回类型。
3.4.2 返回类型
取值也是字符串型、整形、布尔型等。上图中,吃饭,参数是食物,返回是字符串。
同属性类似,也可以在最后,加上一个大括号,去表示这个操作某些其他说明。
3.5 类的职责和约束
如上图,职责可以在类的最下方,再加一个方格来表示。约束,可以在底部,加上一个大括号。这里一般都是约束类的提示,比如取值等。
4.接口(interface)
接口包含操作但不包含属性,且它没有对外界可见的关联。一个类可以实现一个或多个接口,从而支持接口所指定的操作。
在UML中,接口是一种定义类或构件行为的方式。接口描述了类或构件的外部可见的操作,但不提供这些操作的具体实现。每个接口仅描述实际类的行为的有限部分。接口定义了类或构件提供的服务,它定义的服务由类或构件实现。因此,接口跨过了系统的逻辑和物理的界限。一个类可以支持多个接口,效果上或互斥,或覆盖。
接口和类的主要区别如下:
- 实现与继承:类可以实现一个或多个接口,而接口可以被类或其他接口继承。
- 行为的定义与实现:接口定义了对象的行为,但不提供实现。而类不仅定义行为,还提供行为的实现。
- 关系的表示:在UML中,接口和类之间的关系可以通过实现关系和继承关系来表示。实现关系表示一个类实现了一个接口,而继承关系表示一个接口继承了另一个接口或类。
接口和类的联系主要体现在以下几个方面:
- 行为的规范:接口为类提供了一种行为的规范或契约,类通过实现接口来遵循这种规范。
- 多态性:通过实现相同的接口,不同的类可以以统一的方式对外提供服务,从而实现多态性。
- 模块化:接口有助于实现软件的模块化,将功能划分为独立的、可重用的部分。
- 松耦合:使用接口可以降低系统各部分之间的耦合度,提高系统的可维护性和可扩展性。
接口在UML中提供了一种定义和规范行为的方式,与类一起协作以实现软件系统的功能和特性。
接口可以用两种图标来表示:
第一种是用一个矩形图标来表示接口,接口的名字以大写字母"I"开头,表示这是一个接口。
第二种表示法(省略表示法)是将接口表示为一个小圆圈,并和实现它的类用一条线连起来,这种图有时被形象地称作棒糖图(lollipop diagram)。
具体使用哪种图标,取决于实际的绘图工具和建模需求。
下面是接口的几个代码片段例子。
// 定义接口
public interface IDog { void bark(); // 狗叫的方法
} // 创建实现接口的类
public class Puppy implements IDog { @Override public void bark() { System.out.println("汪汪汪!"); // 实现狗叫的方法 }
} // 测试类
public class Test { public static void main(String[] args) { IDog myDog = new Puppy(); // 创建小狗对象 myDog.bark(); // 调用狗叫的方法 }
}
在这个例子中,我们定义了一个名为IDog
的接口,其中包含一个bark
方法,用于描述狗叫的行为。然后,我们创建了一个名为Puppy
的类,该类实现了Dog
接口,并提供了bark
方法的具体实现。最后,在Test
类中,我们创建了一个Puppy
对象,并调用了其bark
方法,从而实现了小狗叫的功能。
不用的狗可能有不同的叫声,但是都用同一个接口去调用,实现了多态。
例如,我们扩展一下上面的代码:
// 定义接口
public interface IAnimal { void makeSound(); // 发出声音的方法
} // 创建实现接口的类 - 小狗
public class Dog implements IAnimal { @Override public void makeSound() { System.out.println("汪汪汪!"); // 狗的叫声 }
} // 创建实现接口的类 - 小猫
public class Cat implements IAnimal { @Override public void makeSound() { System.out.println("喵喵喵!"); // 猫的叫声 }
} // 测试类
public class TestPolymorphism { public static void main(String[] args) { IAnimal myDog = new Dog(); // 创建小狗对象 IAnimal myCat = new Cat(); // 创建小猫对象 // 调用makeSound方法,根据对象的实际类型输出不同的声音 myDog.makeSound(); myCat.makeSound(); // 假设有一个动物数组 IAnimal[] animals = new IAnimal[]{myDog, myCat}; // 遍历动物数组,并调用每个动物的makeSound方法 for (IAnimal animal : animals) { animal.makeSound(); } }
}
注意,在这个例子中,IAnimal
是一个接口,可以看作是一个特殊的父类类型,而Dog
是实现了IAnimal
接口的一个子类。
(待续,下次一起学习类图的4种关系,请关注。)