1.同一种事物,由于条件不同,产生的结果也不同
多态:同一个引用类型,使用不同的实例而执行不同操作。
声明为父类类型,引用的是子类对象。
2.使用多态实现思路:
编写父类
编写子类,子类重写父类方法 ---实现多态的两个要素之一
运行时,使用父类的类型,子类的对象 ---实现多态的两个要素之二
向上转型 Pet pet = new Dog(); //自动执行类型转换
注意:使用父类作为类型,能看到的是父类 Pet 有的属性和方法,看不到子类 Dog 特有的属性和方法,
要想看到子类的属性和方法,要向下转型!
实现多态的两种方式:
方式一:使用父类作为方法形参实现多态
public class Master {
public void feed( Pet pet ) { //使用父类作为方法形参
pet.eat();
}
}
测试方法
… …
Pet pet = new Dog();
Master master = new Master();
master.feed( pet ); //同一种操作方式,不同的操作对象,执行效果也各不相同
… …
方式二:使用父类作为方法返回值实现多态
public Pet getPet(String typeId) { //使用父类作为返回值类型
if (typeId.equalsIgnoreCase("dog")) {
Pet pet = new Dog();
return pet;
} else if (typeId.equalsIgnoreCase("penguin")) {
Pet pet = new Penguin();
return pet;
}
return null;
}
3.使用多态,从父类的角度只能看到父类的特性和方法,看不到子类特有的方法;
如果希望使用子类特有的方法:父类到子类的转换--向下转型(强制类型转换)
例如: Pet pet = new Dog("欧欧", "雪娜瑞");
Dog dog = (Dog) pet;
Penguin png = (Penguin) pet;//报错,必须转换为父类指向的真实子类类型
特别注意:向下转型只能转换为子类原始的真实类型,如果子类的原始类型是狗,向下转型为猫则是不允许的!
4.instanceof 关键字
正是因为向下转向,只能转为子类的原始类型,但是有时候我们并不知道原始类型怎么办?使用 instanceof 关键字,instanceof 就好比照妖镜,照出子类的原始类型。
instanceof 的使用语法:
对象 instanceof 类或接口
instanceof 通常和强制类型转换结合使用,例如:
public void play(Pet pet){
if (pet instanceof Dog) { //如果传入的是狗狗
Dog dog = (Dog) pet;
dog.catchingFlyDisc(); //执行狗狗特有的方法
}else if (pet instanceof Penguin) { //如果传入的是企鹅
Penguin pgn = (Penguin) pet; //执行企鹅特有的方法
pgn.swimming();
}
}
5.多态小结:
多态可以减少类中代码量,可以提高代码的可扩展性和可维护性
向上转型——子类转换为父类,自动进行类型转换
向下转型——父类转换为子类,结合 instanceof 运算符进行强制类型转换
6.接口:
接口作为一种约定和能力。
接口定义使用关键字:interface
接口特性:
接口不可以被实例化 //常作为类型使用
实现类必须实现接口的所有方法
实现类可以实现多个接口 //实现 Java 中多继承效果
接口中的变量都是静态常量
7.如何使用接口:
A.定义接口; //使用 interface 关键字,根据需求设计方法
B.实现接口; //使用 implements 关键字,实现类实现接口的所有方法
C.使用接口; //用多态的方式使用
8.接口表示一种能力、约定
A.接口是一种能力,体现在接口的方法上。
面向接口编程:
一个实现类可以实现多个接口,多个接口之间用逗号分隔。
B.接口是一种约定 体现在接口名称和注释上
有些接口只有名称;
方法的实现方式,要通过注释来约定;
方法的调用,也通过注释来约定。
9.接口有比抽象类更好的特性:
- 可以被多继承
- 设计和实现完全分离
- 更自然的使用多态
- 更容易搭建程序框架
- 更容易更换实现
……
10.接口小结:
|
| Java 接口 |
| 定义 | interface |
| 实现 | implements |
| 静态成员 | 常量 |
| public | 可以显示使用 |
Java 中的接口
属性全都是全局静态常量
方法都是全局抽象方法
无构造方法
一个类可以实现多个接口,非抽象类实现接口时必须实现接口中的全部方法。
抽象类利于代码复用,接口利于代码维护。
子类可以代替父类使用;子孙类可以代替祖先类使用。
实现类可以代替接口使用。--接口类型的变量,指向实现类的对象!
抽象类真正发挥作用靠的是非抽象的子类;
接口真正发挥作用的是靠实现类;
12.接口继承接口:
public interface IDemoA {
public void printAA();
}
public interface IDemoB {
public void printBB();
}
public interface IDemoC extends IDemoA, IDemoB {
public void printCC();
}
在 java 中,extends 的关键字后面若是类只能是一个,若是接口可以多个。
13.继承一个类的同时实现接口:
public class StudentImpl extends Human implements IStudent {...}
有意思事情:---不作要求
通常情况下,父类是看不到子类的特有方法的,但是通过接口实现却有可以的效果。
A.让一个抽象类去实现一个接口,但是接口的真正实现放在抽象类的子类中;
B.使用时,声明为抽象类的类型,指向子类的对象;
C.可以调子类的接口的实现方法!
14.抽象类(abstract)和接口(interface)比较:
- 抽象类不能直接 new 一个实例出来,要通过子孙类发挥作用;
- 单继承实现。
- 抽象类,可以承诺方法,承诺的方法可以有实现也可以没有实现;
- 抽象类的实现类,必须实现父类的所有抽象方法。如果并没有完全实现,他自己也要变成抽象类。
- 抽象类不一定有抽象方法,有抽象方法的类一定要是抽象类。
- 抽象类有构造方法,不能用 new 来实例化,但是非抽象子类实例化时会执行抽象类的构造方法。
- 接口要通过实现类发挥作用;
- 接口,比抽象类更抽象。接口有方法默认实现的时候,要用 default 关键字;
- 接口可以继承接口;接口可以变相的多继承。
- 实现类必须实现接口中承诺的所有的方法。
- 接口还可以作为某种标记,例如序列化接口
- JAVA 是面向接口编程。能用接口的地方我们尽量使用接口,实现松耦合。
- 接口和实现类的关系,不需要有血缘关系,可替换性就比较好。
15.JDK8 中的新特性,接口可以有默认实现: //使用 default 关键字
public interface vehicle { default void print(){ System.out.println("我是一辆车!"); } }
参考链接:http://www.runoob.com/java/java8-default-methods.html
16.==和 equls 区别:
A.基本类型,值比较是使用==;
B.引用类型,==是比较哈希码(地址);equals 比较对象的内容;
PS:引用对象的内容修改---会影响到其他对他的引用
17.类的初始化顺序:http://blog.csdn.net/u011080472/article/details/51330114
非继承关系中的初始化顺序:执行顺序为:
- static 静态代码块和静态成员
- 普通成员
- 构造函数执行
当具有多个静态成员和静态代码块或者多个普通成员时,初始化顺序和成员在程序中申明的顺序一致。
继承关系中的初始化顺序:执行的顺序为:
- 父类静态代码区和父类静态成员
- 子类静态代码区和子类静态成员
- 父类非静态代码区和普通成员
- 父类构造函数
- 子类非静态代码区和普通成员
- 子类构造函数
与非继承关系中的初始化顺序一致的地方在于,静态代码区和父类静态成员、非静态代码区和普通成员是同一级别的,当存在多个这样的代码块或者成员时,初始化的顺序和它们在程序中申明的顺序一致;此外,静态代码区和静态成员也是仅仅初始化一次,但是在初始化过程中,可以修改静态成员的引用
18.Object 类:
- 所有对象的根类。所有的类都可以向上转型为 Object 类;
- 如果一个类没有显示声明继承 Object 类,默认继承 Object 类;
- 如果一个类显示的继承了某个类,那么这个类其实还是继承了 Object 类。
- 因为所有的类显示或隐式继承了 Object 类,所以有 Object 的属性与方法;
- 我们还可以使用 Object 类,实现类似泛型的效果。
18.内部类: 仅作了解即可
在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。
Java 内部类详解 - 海 子 - 博客园 http://www.cnblogs.com/dolphin0520/p/3811445.html
19.匿名对象:用一次,没有变量接收。了解即可
参考链接:http://blog.csdn.net/u010889616/article/details/50465224
匿名对象要注意的事项:
A.我们一般不会给匿名对象赋予属性值,因为永远无法获取到。
B.两个匿名对象永远都不可能是同一个对象。
匿名对象好处:简化书写。
匿名对象的应用场景:
1. 如果一个对象需要调用一个方法一次的时候,而调用完这个方法之后,该对象就不再使用了,这时候可以使用匿名对象。
2. 可以作为实参调用一个函数。
- class Stu {
-
public void study()
-
{
-
System.out.println("Day day hard");
-
}
- };
- public class main {
-
public static void main(String[] args) {
-
new Stu().study();
- //运行一次,直接就被回收掉了,节省内存空间
-
}
- }
20.单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
本质:控制实例数目。
懒汉式步骤
1.私有化构造方法;
2.提供获取实例的静态(static)方法 getInstance();
3.定义存储实例的静态(static)私有(private)属性;
4.控制实例的创建,如果存储实例的属性不为 null,则返回属性值,否则创建实例并对属性赋值。
饿汉式步骤:和上面的区别
1.在定义存储实例的静态(static)私有(private)属性时,直接初始化---new 了;
2.getInstance()不在判断属性为 null 了,直接返回属性值。
练习题:
多态判断的练习题:
创建正方形/三角形/矩形的类,定义这些图形的属性,计算周长和面积!
其他知识:
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于