四、多态性 day12
一个事物的多种形态,父类引用指向子类的对象(向上转型)
父类 变量名=new 子类();
抽象类、接口的使用肯定体现了多态性。(抽象类、接口不能实例化)
1.多态的使用:虚拟方法调用(Virtual)
编译只能调用父类的方法,运行是子类重写父类的方法,
使用前提 :①类的继承关系 ②方法的重写 (同名同参)③父类引用指向子类对象
对象的多态性不适用于属性 编译看左,运行看右
2.向下转型
父类引用转换为子类引用,调用子类特有的方法,需要向下转型,不能直接使用
Man m1=(Man)p2;强制类型转换符
在向下转型之前,先进行a instanceof A ,判断对象a是否为是子类A的实例,a所属类与类A必须是子父类关系,否则编译错误
Person p2=new Man(); //子类赋值给父类 父类类型 变量名=new 子类类型();
Man m1=(Man)p2; //强制类型转换 子类变量 变量名=(子类类型)父类变量;
if (p2 instanceof Man) { //判断p2是否为子类对象
System.out.println("我是男人");
}
!3.== 与equals() 区别
广义上,==比较两个变量本身的值,即两个对象在内存中的首地址
equals() 比较字符串中的内容是否相同
- ==既可以比较基本数据类型(比较值 ),也可以比较引用数据类型(比较内存地址)
- equals() 是一个方法,只能引用数据类型 “ ”
- equals()如果该方法没有被重写过,默认也是==
- 重写equals方法,会比较类中的相应属性是否相等(一般是重写equals方法)
4. JUnit单元测试
JUnit此类是public
5.包装类(Wrapper)
基本数据类型、包装类、String类型转换-
Integer in1=new Integer(12); //int转换成integer包装类
int i1=in1.intValue(); //再调用包装类的value返回值
int num=1; // 基本数据类型转换为包装类
Integer in1=new Integer(num);
- 自动装箱---->包装类
int num1=10;
Integer in1=num2;
2.自动拆箱---->基本数据类型
int num3=in1;
3.基本数据类型、包装类---->String类型转换 valueof(xxx)
public void test4() { //转成String重载的valueof(xxx)
int num1=10;
// String str1=num1+"";
float f1=12.3f;
String str2=String.valueOf(f1); //用valueof转换成String类型
System.out.println(str2);
}
String ------->基本数据类型、包装类 parsexxx(String s)(ParseBoolean)
@Test
public void test() { // string 转成基本数据类型
String str1="123";
int num2=Integer.parseInt(str1);
System.out.println(num2+1);
}
五、static关键字
1.使用
修饰属性、方法、代码块、内部类
1.static修饰属性:静态变量(类变量)
静态变量(类变量)vs非静态变量(实例变量)
静态变量:某一个对象修改静态变量时,会导致其他对象调用此修改过的静态变量( 类.静态变量 )
实例变量:每个对象都独立的拥有一套类中的非静态属性,当修改非静态属性时,不会导致其他属性值修改
静态变量随着类的加载而加载
- 静态变量(类变量)早于对象的创建!!
- 静态变量在内存中只会存在一份,存在方法区的静态域中
1.static修饰方法:类.静态方法
静态方法 只能调用静态的方法和属性,不能使用this、super(无当前对象)
非静态方法:可以调用静态方法和静态属性
单例设计模式
某个类只能存在一个对象实例,
懒汉式
饿汉式
2.final关键字 最终类
-
修饰方法,表示该方法无法被重写
-
修饰类,表示该类无法被继承extends,比如:String类、System类、StrinfBuffer类
-
修饰变量
修饰变量,此时变量就是一个常量(不能变)
修饰局部变量,方法体/形参,当修饰形参时,形参是一个常量;调用此方法时,给变量赋一个实参,只能在方法体内使用此形参,但不能进行重新赋值
static final 用来修饰属性:全局常量
public class FinalTest { final int width=0; //显示初始化 final int left; final int right; { //代码块中初始化 left=1; } public FinalTest(){ //构造器初始化 right=2; }
六、代码块(初始化代码)
代码初始化类、对象
静态代码块vs 非静态代码块
1.静态代码块(先)
static{ }
- 内部由输出语句
- 随着类的加载而自动执行,只执行一次
- 多个静态代码块,按照先后顺序执行
- 只能调用静态的属性、静态的方法,不能调用非静态的结构
2.非静态代码块
- 内部由输出语句
- 随着对象的创建而执行
- 每创建一个对象,就执行一次非静态代码块
- 对 对象进行初始化
- 非静态可以调用静态的属性、方法或非静态
七、抽象类和抽象方法
1.定义:
抽象类是一种继承关系 ,类的设计应该保证父类和子类能够共享特征,有时一个类设计得非常抽象,以至于没有具体得实例,这样得类叫做 抽象类(不能实例化)
2.abstract修饰 类、方法
abstract修饰类:抽象类
- !!此类不能实例化,不能new对象
- 抽象类一定有构造器,便于子类实例化调用(子类对象实例化的全过程) 构造器:方法名与类名相同
2.abstract修饰方法:抽象方法
- 抽象方法只有方法的声明,没有方法体
public abstract void work(); //抽象方法
-
包含抽象方法的类一定是抽象类,反之,抽象类可以没有抽象方法的
-
①若子类重写了父类中的所有抽象方法后,此子类才能实例化,造对象
②如果子类没有重写父类中的所有方法,此子类也是应该抽象类,需要使用abstract修饰
注意:
abstract不能用来修饰属性、构造器,可以定义构造器(子类对象造)
abstract不能用来修饰私有方法、静态方法、final方法、final类
4.模板方法设计模式
易变部分可以抽象出来,供不同子类实现
八、接口
1.定义
-
接口是抽象方法的集合,通常以interface来声明。
-
一个类通常通过继承接口的方式,继承接口的抽象方法
-
接口不能定义构造器,不能实例化
-
接口通过让类的实现(implements)的方式来使用,如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
如果实现类没有实现(覆盖)接口中所有的抽象方法,则此实现类仍为一个抽象类
- 类可以实现多个接口,弥补了是单继承的局限性
class x extends Object implements A{ }
6.接口与接口之间可以多继承
具有相同的行为特征,一个类只有一个父类,但有多个接口
2.设计模式
代理模式(proxy)P353
工厂模式
见day15. exer4!!!)
九、内部类
1.定义:
一个类A声明在另一个类B中, 则类A就是内部类,类B称为外部类,即包含内部类的类称为外部类
2.分类:
成员内部类(静态 、非静态)vs 局部内部类(方法类、代码块、构造器)
成员内部类:
- 不能定义静态变量,但可以访问外部类的所有成员
- 可以被static修饰
3.问题:
1.抽象类和接口有哪些共同点和区别
相同:不能实例化,都可以被继承
抽象类有构造器, 接口:只能声明构造器
2.如何创建静态成员内部类 和非静态成员内部类
Person static dog bird
person.Dog dog=new Person.Dog(); //静态
Person p=new Person(); //非静态>先实例化对象再调用
Person.bird = p.new.bird();
3.问题:
1.抽象类和接口有哪些共同点和区别
相同:不能实例化,都可以被继承
抽象类有构造器, 接口:只能声明构造器
2.如何创建静态成员内部类 和非静态成员内部类
Person static dog bird
person.Dog dog=new Person.Dog(); //静态
Person p=new Person(); //非静态>先实例化对象再调用
Person.bird = p.new.bird();