目录
(接上一章节)
类的属性用于描述类的一个特征,这个特征是类的每个实例所共有的。一个类可以有零到多个属性。类的属性定义语法如下:
[可见性] 属性名称 [:数据类型] [=初始值] [{属性字符串}]
上面的语法中,[]中的内容表示是可选的。可见性默认是私有,属性名称是必要的,其他都可以省略。
下面对以上语法中的各个部分,进行说明:
可见性用于控制该属性被类的外部成员的可访问性。主要有以下四种情况:
+:公有属性(Public),其它类可以访问该属性;
-:私有属性(Private),不能被其它类访问(默认为私有);
#:保护属性(Protected),只能被本类及其派生类访问;
能够准确描述类特征的一个标识符,属性名通常是一个名词或名词短语。一般单字属性使用小写字母,多字属性从第2个单词开始,每个单词的第一个字符要大写。也就是我们说的驼峰命名方法。
很多人对驼峰命名法,有不同的表述,其实,有2种驼峰命名法。
在这里,属性的命名,一般使用小驼峰法。
属性所属的数据类型,如整型、浮点型、字符型,也可以是用户自定义的类型。例如上图中的String,int。?
属性的默认值,在类的实例没有赋其它值时,将采用该值作为该属性的值。例如上图中的xiaobai,就是初始值。
用来指定该属性的其它信息。任何希望进一步描述该属性又没有合适的地方时都可以放在此处。
操作是类的方法或行为,描述了类可以对其属性执行的操作或计算。
在UML中,操作列在类图的第三部分,位于属性之后,并在花括号内。操作的表示包括可见性、名称、参数和返回类型。
类图的表达中,可以只有属性,也可以只有操作,也可以都有。
类的操作定义的语法是:
[可见性] 操作名称 [(参数表)][:返回类型][{属性字符串}]
类的操作的可见性,和熟悉的可见性相同,也是共有、私有和受保护三种。
操作的名称,也是小驼峰命名方法。
注意:如果是操作,没有参数,也要有()标记。
如上图,-eat(food:Food):String操作,有一个参数食物,属于Food类。如果有多个参数,用“,”隔开。
注意,方法如果要表明返回值,需要在参数的括号后面,加上冒号“:”和返回类型。
取值也是字符串型、整形、布尔型等。上图中,吃饭,参数是食物,返回是字符串。
同属性类似,也可以在最后,加上一个大括号,去表示这个操作某些其他说明。
如上图,职责可以在类的最下方,再加一个方格来表示。约束,可以在底部,加上一个大括号。这里一般都是约束类的提示,比如取值等。?
接口包含操作但不包含属性,且它没有对外界可见的关联。一个类可以实现一个或多个接口,从而支持接口所指定的操作。
在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种关系,请关注。)