前言
上一节的多态在这一节将继续介绍
一、抽象类
抽象类:被abstract关键字修饰的类,里面可能会包含抽象方法 当类中没有足够的信息(抽样方法)来描述一个具体的对象时, 抽象类处了不能创建对象之外,类的其他功能都正常(成员变量,构造方法,成员方法) 抽象类一般位于类结构的上层,用来定义有哪些功能,让具体的子类继承实现即可 静态方法不能内修饰为抽象方法. 一个类中可以定义多个抽象方法
抽象方法,定义方法,没有具体的实现。
public abstract class Animal {
private String name;
private int age;
public Animal(){
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public abstract void eat();
public abstract void run();
public void sleep() {
System.out.println("闭着眼睛睡觉");
}
当一个具体的一个类继承抽象类后, 要么重写抽象类中抽象方法. 要么将此类继续声明为抽象美
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void run() {
System.out.println("狗跑的很快");
}
}
public class TestAnimal {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.run();
}
}
二、多态
多态注意事项: 注意成员调用时,分为编译期间和运行期间 编译期间:写代码时 由于类型上升为了父类类型,所以只能调用到父类中定义成员 运行期间:运行代码时,实际调用的是子类中重写的方法 对应非静态成员方法: 编译看左边, 运行看右达
对于静态成员方法和成员变量 编译看左边,运行也是看左边
为了实现多态性,我们将子类类型向上转为了父类类型, 但是一旦类型上升为父类类型,那么就调用不到子类中特有的方法。 这就是多态在某种情况下的缺点 解决办法: 就向下转型,把父类类型转为子类类型
public abstract class Animal {
private String name;
private int age;
int num=10;
public abstract void eat();
public void sleep(){
System.out.println("动物睡觉");
}
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static void show(){
System.out.println("Animal中的show方法");
}
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void CatchMouse(){
System.out.println("猫捉鼠");
}
@Override
public void sleep() {
System.out.println("猫晚上不睡觉");
}
}
public class Dog extends Animal {
int num=20;
@Override
public void eat() {
System.out.println("狗吃屎");
}
public void LookHome(){
System.out.println("狗看门");
}
public static void show(){
System.out.println("dog里面的show方法");
}
}
public class Person {
public void feedAnimal(Animal animal) {
animal.eat();
//判断animal变量,实际运行时表示的是否是Dog类型
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.LookHome();
}
}
}
public class Test {
public static void main(String[] args) {
/*
Dog dog = new Dog();
Cat cat = new Cat();
Person person = new Person();
person.feedDog(dog);
person.feedCat(cat);*/
/*
多态--多种状态
同一个父类,可以表示不同的子类对象,状态就不同了
父类的引用指向子类对象,两个类之间必须是继承关系
把子类类型转为父类类型,同一个父类在不同时候,表示不同状态(子类)
*/
Animal dog = new Dog();
Animal cat = new Cat();
Person person=new Person();
person.feedAnimal(cat);
person.feedAnimal(dog);
}
}
public class Test1 {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
System.out.println(dog.num);
dog.sleep();//对于子类如果没有重写父类中的方法,那么调用的是子类对象中父类的方法
cat.sleep();
Person p = new Person();
p.feedAnimal(dog);
p.feedAnimal(cat);
}
}
三、final关键字
final关键字 可以修饰类,方法,参数,成员变量 final不能修饰抽象类和接口,因为final修饰的类不能被继承 final修饰方法,修饰后方法不能被子类重写 final修饰方法的参数,在方法内部,就不能修改参数值。 final修饰成员变量,
public class Demo {
//情况1:在编码时,值就确定了,就直接进行赋值,此种情况最好加上static关键字,让其在内存中只有一份.
static final int num = 10;
//情况2:每一个对象中都有一个常量,必须在构造方法中为常量进行初始化,以旦初始化后,值都不能更改
final int count;
public Demo(int count) {
this.count = count;
}
public final void test(final int a) {
//a=10;
}
public static void main(String[] args) {
/*Demo demo = new Demo () ;
demo.test( 20);
demo.test( 30);*/
new Demo(10);
new Demo(20);
//demo.num=30;
}
}
总结
多态的内容整理完毕,接下来将要学习关于接口的内容.