UML
统一建模语言或标准建模语言
定义了10种模型图,对应软件开发不同阶段
- 用例图
- 静态图:类图,包图,对象图
- 行为图:状态图和活动图
- 交互图:顺序图和协作图
- 实现图:组件图,部署图
类和类的6种关系
类和类(接口)之间的关系
继承关系(泛化关系)
符号:一条带空心三角箭头的实线,从子类指向父类,或者 子接口指向父类
实现关系
符号:一条带空心三角箭头的虚线箭头实现类指向接口
依赖关系
语法:类B作为类A的方法的参数
符号:带箭头的虚线
关联关系
符号:双向实线箭头
聚合关系()
符号:空心菱形加实现箭头
组合关系
符号:实心菱形加实现箭头
内部类
什么是内部类?
指的是将一个类定义到另一个类的内部类
内部类的使用场合
内部类使用时有特定的规范,应用场景也比较特殊,通常在一些GUI,Android 开发中 。因此在java 开发中,我们要了解内部类的使用及特点,用到较少。
内部类的分类有哪些?
内部类分为四种 :成员内部类,局部内部类,匿名内部类和静态内部类
静态内部类
public class Outer {
private static int radius = 1;
static class StaticInner {
public void visit() {
System.out.println("visit outer static variable:" + radius);
}
}
}
静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式,new 外部类.静态内部类(),如下:
Outer.StaticInner inner = new Outer.StaticInner();
inner.visit();
成员内部类
定义在类的内部,作为成员的类,
特点:
1.可以访问外部类的成员变量和方法
2.如果内部类的属性和外部类的属性重名,默认访问的内部类的属性;如果想要访问外部类的属性需要使用如下方式:
外部类名.this.属性名
3.外部类无法访问内部类的成员。可以通过这种特性,产生访问权限比private 更低
//外部类
public class Outer {
private int aaa;
//成员s内部类
class Inner{
private int bbb;
public Inner() {
super();
}
public Inner(int bbb) {
super();
this.bbb = bbb;
}
public void test(){
System.out.println(bbb);
}
}
}
public static void main(String[] args) {
Outer outer=new Outer();
//内部类的对象,在创建对象时,需要先创建外部类对象,通过外部类对象.new 的形式创建内部类对象
Inner inner = outer.new Inner(1234);
//调用内部类的方法
inner.test();
}
方法内部类
定义在方法内部的类
//外部类
public class Outer {
public void test(){
//不能使用访问修饰符修饰:public protected ,private
class Inner{
private int a=66;
public void demo(){
System.out.println(a);
}
}
Inner inner=new Inner();
inner.demo();
}
public static void main(String[] args) {
new Outer().test();
}
}
匿名内部类
在实现接口时
public class Outer {
private void test(final int i) {
new Service() {
public void method() {
for (int j = 0; j < i; j++) {
System.out.println("匿名内部类" );
}
}
}.method();
}
}
//匿名内部类必须继承或实现一个已有的接口
interface Service{
void method();
}
匿名内部类创建方式:
new 类/接口{
//匿名内部类实现部分
}
除了没有名字,匿名内部类还有以下特点:
1.匿名内部类必须继承一个抽象类或者实现一个接口。
2.匿名内部类不能定义任何静态成员和静态方法。
3.当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。
4.匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
内部类的优点
- 一个内部类对象可以访问创建它的外部类对象和内容包括私有数据
- 内部类不为同一包的其他类所见,具有很好的封装性
- 内部类有效实现了“多重继承”,优化java单继承的缺陷
- 匿名内部类可以方便定义回调。
内部类有哪些应用场景? - 一些多算法 场合
- 解决一些非面向对象的语句块
- 适当使用内部类,使得代码更加灵活和富有扩展性
- 当某个类除了它的外部类,不在被其他的类使用时
局部内部类和匿名内部类访问局部变量时为什么变量必须要加final?
public class Outer {
void outMethod(){
final int a =10;
//方法内部类
class Inner {
void innerMethod(){
System.out.println(a);
}
}
}
}
以上例子,为什么要加final呢?是因为生命周期不一致, 局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的引用依然存在,如果局部内部类要调用局部变量时,就会出错。加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题。
匿名内部类的应用
所实现接口中抽象方法少可以用
public class Test {
public static void main(String[] args) {
String a="sdadfdaff";
String b="asdafafa";
//先按照字符长度比较,然后再按照字母顺序比较
//可以使用匿名内部类实现
int result=new Comparator<String>() {
public int compare(String arg0, String arg1) {
int len=arg0.length()-arg1.length();
if(len==0){
return arg0.compareTo(arg1);
}
return len;
}
}.compare(a, b);
}
}
工厂设计模式
非常常用,在工场设计模式中,什么工厂就用来声场什么对象。当需要根据客户不同需求创建不同对象时,可以使用工厂设计模式解决。
实例工厂(动态工厂)
public abstract class Pizza {
private String name;
private int size;
public Pizza(String name, int size) {
super();
this.name = name;
this.size = size;
}
public Pizza() {
super();
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public abstract void show();
}
//超级至尊
public class SuperPizza extends Pizza {
private boolean hasDouble;
public SuperPizza() {
super();
}
public SuperPizza(String name, int size,boolean hasDouble) {
super(name, size);
this.hasDouble=hasDouble;
}
public boolean isHasDouble() {
return hasDouble;
}
public void setHasDouble(boolean hasDouble) {
this.hasDouble = hasDouble;
}
@Override
public void show() {
System.out.println("超级至尊完成:"+getName()+",尺寸"+getSize()+",是否夹心"+hasDouble);
}
}
public class LongXia extends Pizza{
private int num;
public LongXia() {
super();
}
public LongXia(String name, int size,int num) {
super(name, size);
this.num=num;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void show() {
System.out.println("大龙虾披萨制作完成:"+getName()+",尺寸"+getSize()+",有"+num+"只大龙虾!");
}
}
工厂类
public class PizzaFactory {
// 方法名一般叫getIntance
public Pizza getPizza(int option) {
Pizza pizza = null;// 先声明Pizza类型的变量
switch (option) {
case 1:
pizza=new SuperPizza("至尊披萨",8,true);
break;
case 2:
pizza=new LongXia("龙虾披萨",8,6);
break;
default:
System.out.println("操作有误");
break;
}
return pizza;
}
}
//要求制作pizza
/**
* 1.抽取抽象类Pizza,name 属性,size 属性 ,show 方法
* 2.编写对应具体类
* 超级至尊
* 麻辣小龙虾
* 3.来客户,根据客户不同的输入,返回对应pizza
* 4,提供一个Pizza工厂,接收一个 参数,返回对应的pizza
* @author lenovo
*
*/
public abstract class Test {
public static void main(String[] args) {
//创建一个工厂对象
PizzaFactory factory=new PizzaFactory();
//开始点餐
Pizza pizza = factory.getPizza(2);
//展示
pizza.show();
}
}
静态工厂
public class PizzaFactory {
// 方法名一般叫getIntance
public static Pizza getPizza(int option) {
Pizza pizza = null;// 先声明Pizza类型的变量
switch (option) {
case 1:
pizza=new SuperPizza("至尊披萨",8,true);
break;
case 2:
pizza=new LongXia("龙虾披萨",8,6);
break;
default:
System.out.println("操作有误");
break;
}
return pizza;
}
}
public static void main(String[] args) {
Pizza pizza = PizzaFactory.getPizza(2);
pizza.show();
}