3. 对象类型的转换
3.1 类的向上转型
向上转型就是把子类对象赋值给父类类型的变量。
首先,创建一个Person类:
public class Person {
public Person(String name) {
System.out.println("您好,我叫"+name);
}
}
然后,创建一个Student类,继承Person类:
public class Student extends Person{
public Student(String name) {
super(name);
}
}
最后,在Demo类中进行实例化:
package JAVALearining;
public class Demo {
public static void main(String[] args) {
Person tom = new Student("tom");
}
}
得到结果:
您好,我叫tom
由于向上转型是从一个叫具体的类到较抽象的类,所以它总是安全的。
3.2 类的向下转型
向下转型是将较抽象的类转换为较具体的类。
子类对象总是父类的一个实例,但父类对象不一定是子类的实例。
上述图片中可能有错误,具体看下面的例子。新建Doctor类,继承Person类:
public class Doctor extends Person{
public Doctor(String name) {
super(name);
}
}
然后在实例中对Doctor进行实例化:
public class Demo {
public static void main(String[] args) {
Person tom = new Student("tom");
Person jack = new Doctor("jack");
Doctor doc = (Doctor)jack;
}
}
运行后,系统没有报错。
您好,我叫tom
您好,我叫jack
讲真,没明白,这么做的意义何在……不强行转换不是也可以输出吗?视频中的例子举的不好,具体可以参考书上P179。
4. instanceof关键字
使用instanceof
操作符判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。语法如下:
myobjcet instanceof ExampleClass
- myobject:某类的对象引用
- ExampleClass:某个类
使用instanceof操作符的表达式返回值为布尔值。如果返回值为true,说明myobject对象为ExampleClass的实例对象;如果返回false,说明myobject对象不是ExampleClass的实例对象。
例子:
public class Computer {//电脑
public static void main(String[] args) {
Pad ipad = new Pad();
LenovoPad lenovoPad = new LenovoPad();
System.out.println("Pad是否继承自电脑:"+(ipad instanceof Computer));
System.out.println("LenovoPad是否继承自Pad:"+(lenovoPad instanceof Pad));
System.out.println("LenovoPad是否继承自Computer:"+(lenovoPad instanceof Computer));
System.out.println("ipad是否继承自LenovoPad:"+(ipad instanceof LenovoPad));
}
}
class Pad extends Computer{//平板电脑
}
class LenovoPad extends Pad{//联想平板电脑
}
结果:
Pad是否继承自电脑:true
LenovoPad是否继承自Pad:true
LenovoPad是否继承自Computer:true
ipad是否继承自LenovoPad:false
5. 方法的重载
为了让方法名相同而形参不同的构造方法同时存在,必须用到方法重载。
方法的重载就是在同一个类中允许同时存在一个以上的同名方法,只要这些方法的参数个数或类型不同即可。
public class Demo {
public static void main(String[] args) {
System.out.println("调用add(int a)方法:" + add(1));
System.out.println("调用add(int a, int b)方法:" + add(1, 2));
System.out.println("调用add(int a, double b)方法:" + add(1, 2.1));
System.out.println("调用add(double b, int a)方法:" + add(1.1, 2));
}
static int add(int a) {//最普通方法
return a;
}
static int add(int a, int b) {//定义与第一个方法参数个数不同的方法
return a + b;
}
static int add(int a, double b) {//定义与第二个方法参数类型不同的方法
return (int)(100);
}
static int add(double b, int a) {//定义与第二个方法参数顺序不同的方法
return (int)(-100);
}
}
得到结果:
调用add(int a)方法:1
调用add(int a, int b)方法:3
调用add(int a, double b)方法:100
调用add(double b, int a)方法:-100
6. 多态
利用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。
例子:
class Animal {
void move() {
}
}
class Fish extends Animal {
void move() {// 重写move方法
System.out.println("Swim");
}
}
class Bird extends Animal {
void move() {// 重写move方法
System.out.println("Fly");
}
}
public class Demo {
public static void main(String[] args) {
Animal tom = new Fish();
tom.move();
tom = new Bird();
tom.move();
}
}
得到结果:
Swim
Fly
可以看到,同样的对象tom调用相同的方法move(),得到不同的结果。
需要注意的是,第一次实例化和第二次实例化写法不同,如果写法相同会报错。
7. 抽象类与接口
7.1 抽象类
语法如下:
public abstract class Test{
abstract void testAbstract();
}
其中,abstract是定义抽象类的关键字。
使用abstract关键字定义的类称为抽象类,而使用这个关键字定义的方法称为抽象方法。抽象方法没有方法体,这个方法本身没有任何意义,除非它被重写,而承载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承之外没有任何意义。
反过来讲,如果声明一个抽象的方法,就必须将承载这个抽象方法的类定义为抽象类,不可能在非抽象类中获取抽象方法。因此,只要类中有一个抽象方法,此类就被标记为抽象类。
图:抽象类继承关系
7.2 接口
接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。
接口使用interface关键字进行定义,其语法如下:
public interface drawTest{
void draw();
}
- public:接口可以像类一样被权限修饰符修饰,但public关键字仅限用于接口在与其同名的文件中被定义。
- interface:定义接口关键字。
- drawTest:接口名称。
例子:
首先,创建一个接口:
public interface DrawInterface {
public void draw();
}
接下来,创建四边形类实现接口:(注意,在实现接口后系统会要求重写draw()方法)
public class Quar implements DrawInterface{
@Override
public void draw() {
System.out.println("绘制四边形");
}
}
同理,创建正方形类:
public class Square implements DrawInterface{
@Override
public void draw() {
System.out.println("绘制正方形");
}
}
最后,创建Demo类:
public class Demo {
public static void main(String[] args) {
DrawInterface d1 = new Quar();
d1.draw();
DrawInterface d2 = new Square();
d2.draw();
}
}
运行后,得到结果:
绘制四边形
绘制正方形
这两个类没有继承关系,但是却实现了同一个抽象方法。