Java基础-面向对象进阶-多态, 包, final, 权限修饰符,代码块
多态
多态的概述
- 多态: 对象的多种形态
- 多态的前提
- 有继承/实现关系
- 有父类引用指向子类对象
- 有方法的重写
- 多态的好处
- 使用父类型作为参数, 可以接收所有子类对象, 体现多态的扩展性和便利
多态中调用成员的特点
- 调用成员变量的特点: 编译看左边, 运行看左边
- 调用成员方法的特点: 编译看左边, 运行看右边
java
public class demo {
public static void main(String[] args) {
// 多态调用成员的特点
Animal a = new Dog();
System.out.println(a.name);
a.show();
}
}
class Animal{
public String name = "动物";
public void show()
{
System.out.println("Animal");
}
}
class Dog extends Animal{
private String name = "狗";
public void show()
{
System.out.println("Dog");
}
}
多态的优势和弊端
- 多态的优势
- 方法中, 使用父类型作为参数, 可以接收所有子类对象
- 多态的弊端
- 不能使用子类的特有功能
- 引用数据类型的类型转换
- 自动类型转换:
Person p = new Student()
- 强制类型转换:
Student s = (Student)p
- 自动类型转换:
- 强制类型转换解决什么问题
- 可以转换成真正的子类类型, 从而调用子类独有功能
- 转换类型与真实对象类型不一致会报错
- 转换时用
instanceof
关键字进行判断
多态练习
-
demo
javapublic class demo { public static void main(String[] args) { /** 多态综合练习 * 根据需求完成代码: * 1.定义狗类 * 属性: * 年龄,颜色 * 行为: * eat(String something)(something表示吃的东西) * 看家lookHome方法(无参数) * * 2.定义猫类 * 属性: * 年龄,颜色 * 行为: * eat(String something)方法(something表示吃的东西) * 逮老鼠catchMouse方法(无参数) * * 3.定义Person类//饲养员 * 属性: * 姓名,年龄 * 行为: * keepPet(Dog dog,String something)方法 * 功能:喂养宠物狗,something表示喂养的东西 * 行为: * keepPet(Cat cat,String something)方法 * 功能:喂养宠物猫,something表示喂养的东西 * 生成空参有参构造,set和get方法 * 4.定义测试类(完成以下打印效果): * keepPet(Dog dog,String somethind)方法打印内容如下: * 年龄为30岁的老王养了一只黑颜色的2岁的狗 * 2岁的黑颜色的狗两只前腿死死的抱住骨头猛吃 * keepPet(Cat cat,String somethind)方法打印内容如下: * 年龄为25岁的老李养了一只灰颜色的3岁的猫 * 3岁的灰颜色的猫眯着眼睛侧着头吃鱼 * 5.思考: * 1.Dog和Cat都是Animal的子类,以上案例中针对不同的动物,定义了不同的keepPet方法,过于繁琐,能否简化,并体会简化后的好处? * 2.Dog和Cat虽然都是Animal的子类,但是都有其特有方法,能否想办法在keepPet中调用特有方法? */ Person p1 = new Person("老王", 30); Person p2 = new Person("老李", 25); Dog dog = new Dog(2, "黑"); Cat cat = new Cat(3, "灰"); p1.keepPet(dog, "骨头"); p2.keepPet(cat, "鱼"); } }
-
Animal
javapublic class Animal { private int age; private String color; public void eat(String something){ System.out.println("吃"+something); } public Animal() { } public Animal(int age, String color) { this.age = age; this.color = color; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } }
-
Dog
javapublic class Dog extends Animal{ public Dog() { } public Dog(int age, String color) { super(age, color); } public void lookHome(){ System.out.println("看家"); } @Override public void eat(String something) { System.out.println(getAge()+"岁的"+getColor()+"颜色的狗两只前腿死死的抱住"+something+"猛吃"); } }
-
Cat
javapublic class Cat extends Animal{ public Cat() { } public Cat(int age, String color) { super(age, color); } public void catchMouse() { System.out.println("抓老鼠"); } @Override public void eat(String something) { System.out.println(getAge()+"岁的"+getColor()+"颜色的猫眯着眼睛侧着头吃"+something); } }
-
Person
javapublic class Person { private String name; private int age; public Person() { } public Person(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 void keepPet(Animal a, String something){ if(a instanceof Dog dog){ System.out.println("年龄为"+age+"岁的"+name+"养了一只"+a.getColor()+"的"+a.getAge()+"岁的狗"); a.eat(something); dog.lookHome(); }else if(a instanceof Cat cat){ System.out.println("年龄为"+age+"岁的"+name+"养了一只"+a.getColor()+"的"+a.getAge()+"岁的猫"); a.eat(something); cat.catchMouse(); } } }
包
- 包的作用
包就是文件夹,用来管理各种不同功能的Java类 - 包名书写的规则
公司域名反写 + 包的作用,需要全部英文小写,见名知意 - 什么是全类名
包名 + 类名 - 什么时候需要导包?什么时候不需要导包?
- 使用同一个包中的类时,不需要导包
- 使用java.lang包中的类时,不需要导包
- 其他情况都需要导包
- 如果同时使用两个包中的同名类,需要用全类名
final
- final修饰方法: 最终方法, 不能被重写
- final修饰类: 最终类, 不能被继承
- final修饰变量: 是常量, 不能被修改
- 基本数据类型: 变量的值不能修改
- 引用数据类型: 地址值不能修改, 内部的属性值可以修改
权限修饰符
实际开发中, 一般只用private和public
- 成员变量私有
- 方法公开
- 注意: 如果方法中的代码是抽取其他方法中共性代码, 这个方法一般也私有
代码块
- 局部代码块
- 提前结束变量的生命周期(已淘汰)
- 构造代码块
- 抽取构造方法中的重复代码(不够灵活)
- 静态代码块的作用
- 数据的初始化
来源
黑马程序员. 阿玮Java零基础