面向对象特征–多态
同一种事物,在不同时刻表现不同的状态
存在的三个必要条件
要有继承(包括接口的实现)(前提条件)
要有重写(前提条件)
父类引用指向子类对象(当编译期间类型是父类,运行期间类型是子类)
package day5.demo3;
/**
继承:
在已有类的基础上,派生出新的类,新类可以拥有父类非私有的属性,方法
提高代码可重用性,可扩展性
是一种is-a关系 猫是动物,狗是动物
Animal 称为 父类/基类
*/
public abstract class Animal {
int ss=10;
private String name;
private int age;
public abstract void eat();
public static void sleep(){
System.out.println("睡觉");
}
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name ;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
package day5.demo3;
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("吃鱼");
return;
}
}
package day5.demo3;
/*
在Animal的基础上派生出 狗类
Java中一个类只能直接继承一个父类
*/
public class Dog extends Animal {
private String type;
int ss=5;
@Override
public void eat() {
System.out.println("吃骨头");
}
public void play(){
System.out.println("狗会玩");
}
public void setType(String type){
this.type=type;
}
public String getType(){
return type;
}
}
package day5.demo3;
public class Text {
/*
多态:
同一个事物 在不同时刻表现的不同状态
前提条件:
继承 只有继承 父类才可以表示子类
方法重写 在顶层父类中会定义一些抽象方法(没有方法实现) 只是作一些功能定义
子类继承后 重写父类中没有实现的方法
父类引用指向子类对象
*/
//编译看左边,运行看右边 针对成员方法
public static void main(String[] args) {
Animal dog=new Dog();
dog.eat();
//编译运行都看左边 静态方法
dog.sleep();
//编译运行都看左边 成员变量
System.out.println(dog.ss);
Animal cat=new Cat();
cat.eat();
}
}
方法参数具有多态性
特点:提高代码的扩展性
package day5.demo3;
public class Text1 {
public static void main(String[] args) {
//方法参数多态性的好处:提高代码的扩展性
Animal dog=new Dog();
Animal cat=new Cat();
Text1 t=new Text1();
t.feedAnimal(cat);
t.feedAnimal(dog);
}
public void feedAnimal(Animal animal){
animal.eat();
}
//非多态方法
/*public static void main(String[] args) {
Dog dog=new Dog();
Cat cat=new Cat();
Text1 t=new Text1();
t.feedCat(cat);
t.feedDog(dog);}
public void feedCat(Cat cat){
cat.eat();
}
public void feedDog(Dog dog){
dog.eat();
}*/
}
向上转型:
作用:提高程序的扩展性。
向下转型:
作用:为了使用子类中的特有方法。
package day5.demo3;
public class Text2 {
public static void main(String[] args) {
Animal animal = new Dog();//向上转型
//多态问题: 父类类型不能访问子类特有的方法
//解决办法: 向下转型
Dog dog=(Dog)animal;// 目的是想要使用子类中的特有的方法
dog.play();
String s="sa";
Object obj=s; //object中包含String类型的方法
if(obj instanceof Dog){ //instanceof 大类型 instanceof 小类型 判断俩边对象类型是否相同
Dog d=(Dog)obj; //Dog类中没有String类型
}else {
System.out.println("不是dog类型");
}
}
}
final关键字
用于声明属性,方法和类
属性:定义就必须直接赋值或者在构造方法中进行赋值,并且后期都不能修改。
方法:子类里不可被覆盖(重写)。
类:不能被定义为抽象类或是接口,不可被继承。
final属性赋值
在声明时同时赋值,一般与static一起使用
声明时如果不赋值,则必须在构造方法中逐一赋值
总的来说:保证创建每一个对象的时候,final属性的值都是确定的。
package day5.demo4;
/*
final修饰类,方法,属性
final 修饰的类不能被其他类继承
public final class Father {
}
*/
public class Father{
/*
* final修饰的属性为常量,值不可改变,将其修饰为static,节省内存空间,所以对象关享一份。
* */
final static int NUM=2;//所以对象共享一份
final int count;//每个对象都有一个常量
public Father() {
this.count = 5;
}
public void test(){
}
/*
final修饰的方法不能被重写
public final void test(){
}*/
public static void main(String[] args) {
new Father();
testFinal(1);
testFinal(2);
}
public static void testFinal(final int a){
//a=10;
System.out.println(a);
}
}
package day5.demo4;
public class Son extends Father{
public Son(int count) {
super();
}
}
抽象类
类中没有包含足够的信息来描绘一个具体的对象
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
用abstract修饰的类一定是抽象类
如果一个类中包含有抽象方法,那么这个类一定是抽象类
一个类如果是抽象类,它可以没有抽象方法
抽象方法
是一种特殊的方法:它只有声明,而没有具体的实现
必须用abstract关键字进行修饰
package day5.demo5;
/*
抽象类中有没有未实现功能的方法
被abstract修饰的类
如果一个类中有抽象方法(没有实现的方法),那么这个类一定是抽象类
如果一个类是抽象类 不一定有抽象方法
*/
public abstract class Animal {
int num;//成员变量
//构造方法
public Animal(){
}
//抽象方法
public abstract void eat();
//成员方法
public void sleep(){
}
//静态方法
public static void drink(){
}
}
package day5.demo5;
//public abstract class Dog extends Animal{
/*
如果一个类继承了抽象类:
要么重写抽象类中所以抽象方法
要么将当前类也声明成抽象类
*/
public abstract class Dog extends Animal{
}
抽象类,抽象方法,在软件开发过程中都是设计层面的概念。