类图、类与类的关系、多态
文章目录
一、多态
多态是指调用同一种方法,由于子类|实现类的不同可能会有不同的行为
前提 —— 首先要存在继承或实现关系
子类|实现可以有多个,使用父类|接口类型存储子类|实现类创建对象,
调用同一个方法会出现不同的实现
多态与方法有关,与参数无关
多态之向上转型(用的更多)
父类型——存储子类型创建的对象
接口——存储实现类创建的对象
父类型/接口 对象名 = new 子类/实现类();
父类引用指向子类对象
对象只能调用子类重写的父类方法(实现类实现或重写的方法)或者调用父类方法,而不能调用子类特有的方法
多态之向下转型
在向上转型的基础上,
将父类型|接口类型 转换为子类|实现类
父类型/接口 对象名1 = new 子类/实现类();
子类/实现类 对象名2 = 对象名1;
instance of 关键字
用来判断父类引用指向的是谁的实例
对象名 instance of 类名(返回boolean值)
使用的前提条件
对象名的类型与类名存在继承或实现关系
简单工厂设计模式
根据参数的值判断需要实例化哪个子类对象
例如以下getCar()方法,传入一个字符串指明车型,返回一个指向子类对象的父类实例
public class CarFactory {
public static Car getCar(String carName){
Car car = new Car();
switch (carName){
case "baoma":
System.out.println("BaoMa");
car = new BMW();
break;
case "benchi":
System.out.println("BenChi");
car = new BigBen();
break;
case "lanbojini":
System.out.println("LanBoJiNi");
car = new LanBoJiNi();
break;
default:
System.out.println("ERROR!!!");
break;
}
return car;
}
}
内部类
指的是定义在一个类内部的类,
支持所有的权限修饰符(局部内部类只能使用默认的)
内部类分为
- 非静态成员内部类
- 静态成员内部类
- 局部内部类
- 匿名内部类
类中可以有:
- 属性 / 成员变量
- 方法
- 代码块
- 内部类
成员内部类
非静态成员内部类
-
与属性、方法等同级
-
不能拥有静态属性和静态方法
-
成员内部类可以直接使用外部类的属性(静态与否都可以)
-
可以直接调用外部类的方法(无论是否静态)
-
当内部类与外部类属性出现同名时,可以使用
外部类名字.this.变量名
-
外部类不能直接使用内部类的属性,内部类创建对象前提必须创建内部类对象
内部类创建对象前提必须外部类已经创建了对象——内部类可以直接用外部类属性原因
外部类就不一定了
创建对象:
-
外部类——正常创建
-
根据外部类创建内部类——
外部类型.内部类型 内部类对象名 = 外部类对象名.new 内部类型();
例
package com.bjsxt.innerClassDemo1;
/*
* 类中的类就是内部类
* 非静态内部类
* 静态内部类
* 局部内部类
* 匿名内部类
*
* 成员内部类的特征
* 1.可以使用四个访问修饰符
* 2.内部类中可以直接使用外部类的成员变量
* 3.内部类可以直接调用外部类的成员方法
* 4.在内部类方法中, 通过外部类类名.this.成员变量名区分内部类和外部类的同名成员变量
* 5.外部类是不能直接使用内部类的成员变量和成员方法的
* */
public class OuterClass{
// 成员变量
private String name ="OuterClass name";
// 成员方法
public void showName(){
System.out.println(name);
}
// 成员内部类
private class InnerClass{
//成员变量
String username="innerclass username";
//成员方法
public void showUsername(){
System.out.println(username);
/* System.out.println(name);
System.out.println(OuterClass.this.name);
showName();*/
}
// 构造方法
public InnerClass(){
}
}
}
//创建内部类对象
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
静态成员内部类
特点
-
可以存在静态资源
-
只可以访问外部类的静态资源
-
静态成员内部类与外部类的属性名相同时,只能使用
外部类.属性名()
-
外部类不能直接调用非静态内部类的成员变量、成员方法,必须new对象后才可以使用
但是外部类可以使用
内部类名.静态属性名 内部类名.静态方法名
直接调用静态内部类的成员变量
-
创建对象
外部类型.内部类名 内部对象名 = new 外部类型名.内部类型()(注意此处外部类型名,如果是非静态,外部类型名后是要跟个括号的,但此处不用)
例
package com.bjsxt.innerClassDemo2;
/*
* 类中的类就是内部类
* 普通内部类
* 静态内部类
* 局部内部类
* 匿名内部类
*
* static修饰内部类 静态内部类 静态内部类只能直接使用外部类的静态成员
* */
public class OuterClass{
// 成员变量
private static String name ="OuterClass name";
// 成员方法
public static void showName(){
System.out.println(name);
}
// 构造方法
public OuterClass(){
}
public void testa() {
InnerClass ic =new InnerClass();
System.out.println(ic.username);
ic.showUsername();
}
// 成员内部类
static class InnerClass {
//成员变量
String username="innerclass username";
//成员方法
public void showUsername(){
System.out.println(username);
System.out.println(name);
showName();
}
// 构造方法
public InnerClass(){
}
}
}
//创建内部类对象
OuterClass.InnerClass b = new OuterClass.InnerClass();
局部内部类(了解即可)
1、 定义在方法中,作用只限于方法中
package com.bjsxt.innerClassDemo3;
/*
* 1.在方法中声明的类就是局部内部类
* 2.仅仅在当前方法中可用
* 3.局部内部类中 只能直接使用外部类的常量
* 4.JDK1.8开始,局部内部类中使用常量的final关键字可以省略不写
* */
public class Test1 {
public static void main(String[] args) {
final int i=10;
class A{
String name;
public void showName(){
System.out.println(i);
}
public A(){
}
}
A a =new A();
}
public static void method(){
}
}
注意:局部内部类访问所在方法的局部变量,要求局部变量必须使用final修饰。JDK1.8中final可以省略,但是编译后仍旧会加final。
匿名内部类
匿名内部类就是内部类的简化写法
用在方法中,作用于整个方法
作用——继承了某个类,或者实现了某接口,一般需要只使用一次子类或接口中才会这样使用
- 因为没有类名所以没有构造方法
- 匿名内部类没有访问修饰符
- 匿名内部类自定义的方法和属性的get() set() 方法往往是无法调用的
- 只能使用匿名内部类的代码块对其中的属性进行初始化
使用语法
public static void main(String[] args) {
int a = 0;
NoNameInte noNameInte = new NoNameInte(){
@Override
public void hello() {
System.out.println("Hello");
}
};
}
类与类之间的关系
-
继承关系——Generalization
类与类,接口与接口
-
实现关系——Realization
一个类实现了一个或者多个接口
-
依赖关系——Dependency
某个类的某个方法中形参为另一个类
public class Student{ public void consult(Teacher teacher){} public void play(){} }
public class Teacher{}
-
关联关系——Association
关联关系是一种强语义关系,这种关系不是临时的,不是偶然的,是一种长久的关系
比如某个类中的一个属性为另一个类的对象,
两者互相有一对多,或多对多的关系
例如一个老师可以教很多学生,而一个学生只听一个老师的课
public class Teacher1{ private Student1[] students; }
public class Student1{ private Teacher1 teacher; }
-
聚合关系——Aggregation
属于关联关系中的一种特例,表示整体和部分的关系即 has - a(即一对一) 。
聚合是整体和部分的关系。
这种整体和部分是可以分离的。例如:公司和员工,班级和学生 。拆分后各部分仍然各自有意义
public class Company{ private Employee[] employees; }
public class Employee{ private Company company; }
-
组合关系——Composition
组合关系属于聚合关系的特例,
也表示整体和部分之间的关系,
两者一旦相互脱离就会失去意义,
比如汉字与句子,汉字脱离句子也就会失去了整体在一起的意义。
又例如人与大脑,互相不可分割,否则都将失去意义
public class Brain{ private Person1 person; }
public class Person1{ private Brain brain; }