多态
什么是多态:简单的理解就是事物在不同情况下具有多种形态。
多态的必要条件:要有继承,方法重写,而且要有子类对象指向父类(父类 对象名=new 子类())。
例:
public class Animal {
int age;
String name;
public void eat(){
System.out.println("吃");
}
}
public class Dog extends Animal {
public void eat(){
System.out.println("狗吃骨头");
}
}
public class Cat extends Animal {
public void eat(){
System.out.println("猫吃鱼");
}
}
public class Test {
public static void main(String[] args) {
Animal animal1=new Cat();
Animal animal2=new Dog();
animal1.age=5;
animal1.name="jerro";
animal2.age=6;
animal2.name="timm";
System.out.println(animal1.name+" 年龄:"+animal1.age);
animal1.eat();
System.out.println(animal2.name+" 年龄:"+animal2.age);
animal2.eat();
}
}
输出:
jerro 年龄:5
猫吃鱼
timm 年龄:6
狗吃骨头
特点:
访问特点:访问成员变量,编译看等号左边,运行看左边。
访问成员方法,编译看等号左边,运行看右边。
访问静态方法,编译看左边,运行看左边。(静态方法其实谈不上重写)。
访问构造方法,创建子类对象时,会访问父类构造方法,对父类数据进行初始化。
多态的好处:提高了代码的维护性(同继承);提高了代码的延展性。
多态的弊端:父类不能访问子类的特有方法。若想访问子类的特有方法,需将父类对象向下转型为子类对象。
向上转型和向下转型:
子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。Animal animal1 = new Cat();Animal animal2=new Dog();将子类对象Cat和Dog转化为父类对象Animal。这个时候animal这 个引用调用的方法是子类方法。
向下转型的前提是父类对象指向的是子类对象(也就是说,在向下转型之前,它得先向上转型)
向下转型只能转型为本类对象(猫是不能变成狗的)。
例:孔子装爹
//孔子爹 public class KongFather { int age=55; public void teach(){ System.out.println("孔子爹教英语"); } }
//孔子 public class KongZi extends KongFather{ int age=30; public void teach(){ System.out.println("孔子教论语"); } public void play(){ System.out.println("孔子喜欢玩英雄联盟"); } }
//英语培训特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了 //但是还有人来请,就剩孔子在家,价格还挺高。孔子一想,我是不是可以考虑去呢? //然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹 public class Test2 { public static void main(String[] args) { KongFather Kong = new KongZi(); System.out.println(Kong.age); Kong.teach(); KongZi kong=(KongZi)Kong; System.out.println(kong.age); Kong.teach(); kong.play(); } }
输出:
55
孔子教论语
30
孔子教论语
孔子喜欢玩英雄联盟
抽象类
通常可以说四边形具有4条边,或者更具体一点,平行四边形是具有对边平行且相等特性的特殊四边形,等腰三角形是其中两条边相等的三角形,这些描述都是合乎情理的,但对于图形对象却不能使用具体的语言进行描述,他有几条边,究竟是什么图形,没有人说的清楚,这种类被定义为抽象类。
抽象类的定义格式:
public abstract class Test(){ //定义抽象类 abstract void teatAbatract();//定义抽象方法 }
抽象类特点:1.抽象类中不一定有抽象方法,有抽象方法的一定是抽象类。
2.抽象类的子类要么是抽象类,要么重写抽象类中的抽象方法。
3.抽象类有构造方法但不能实例化,抽象类中的构造方法用于子类访问父类时父类数据的初始化。
抽象类的成员特点:1.成员变量:既可以时常量,也可以是变量。
2.构造方法:用来子类访问父类时数据的初始化。
3.成员方法:既可以是抽象的,也可以是非抽象的。
例:
public abstract class Teacher { Teacher(){ } String name; int age; public abstract void teach(); }
public class Basic extends Teacher implements Interface{ @Override public void teach() { System.out.println("教基础班"); } }
public class GetJob extends Teacher implements Interface{ @Override public void teach() { System.out.println("教就业班"); } }
public static void main(String[] args) { Teacher teacher1 = new Basic(); Teacher teacher2 = new GetJob(); teacher1.name = "张三"; teacher1.age = 30; teacher2.name = "李四"; teacher2.age = 32; System.out.println("名字 :" + teacher1.name + " 年龄 :" + teacher1.age); teacher1.teach(); System.out.println("-----------------------"); System.out.println("名字 :" + teacher2.name + " 年龄 :" + teacher2.age); teacher2.teach(); } }
输出:
名字 :张三 年龄 :30
教基础班
-----------------------
名字 :李四 年龄 :32
教就业班
abstract关键字不能和哪些关键字共存:
static:被static修饰的方法不存在重写,无意义。
private:private修饰的只能在奔雷在中使用。
final:final修饰的变量不能被重写赋值,被修饰的方法不能被重写,被修饰的类不能被继承。
接口
接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。
接口使用interfa关键字进行定义,语法为:
public interface Test(){ void draw();//接口内的方法,省略abstract关键字 }
一个类实现一个接口可以使用implements关键字,代码为:
public class Parallelogram extends qa implements Test{ ...// }
接口不能实例化,要用多态的方法去实例化。
接口的子类可以是具体类也可以是抽象类,但是意义不大。
接口成员的特点:
成员变量:只能是静态的常量。
构造方法:接口中没有构造方法。
成员方法:只能是抽象方法,具有默认修饰符:public abstract,但建议手动给出。
类与类,类与接口,接口与接口的关系:
类与类:继承关系,只能单继承,支持多层继承。
类与接口:实现关系,可以单实现,也可以多实现,也可以在继承一个类的同时实现多个接口。
接口与接口:继承关系,可以单继承,也可以多继承。
抽象类和接口的区别:
抽象类:
成员变量:可以是变量,也可以是常量。
构造方法:有构造方法。
成员方法:可以抽象方法,也可以非抽象方法。
接口:
成员变量:只可以常
成员方法:只可以抽象
构造方法:没有
类与类之间的关系:继承,单继承。
类与接口之间的关系:实现,单实现与多实现。
接口与接口之间的关系:继承,单继承,多继承。
例:
public abstract class Teacher { Teacher(){ } String name; int age; public abstract void teach(); }
public class Basic extends Teacher implements Interface{ @Override public void teach() { System.out.println("教基础班"); } @Override public void japanese() { System.out.println("这个老师学会了日语"); } }
public class GetJob extends Teacher implements Interface{ @Override public void teach() { System.out.println("教就业班"); } @Override public void japanese() { System.out.println("这个老师学会了日语"); } }
class SuperEx { public static void main(String[] args) { Teacher teacher1 = new Basic(); Teacher teacher2 = new GetJob(); teacher1.name = "张三"; teacher1.age = 30; teacher2.name = "李四"; teacher2.age = 32; System.out.println("名字 :" + teacher1.name + " 年龄 :" + teacher1.age); teacher1.teach(); // ((Basic) teacher1).japanese(); System.out.println("-----------------------"); System.out.println("名字 :" + teacher2.name + " 年龄 :" + teacher2.age); teacher2.teach(); // ((GetJob) teacher2).japanese(); } }
public interface Interface { void japanese(); }