课程链接:https://www.bilibili.com/video/BV1Rx411876f
开始时间:2020-10-16
多态
父类型的引用子类型对象
package test001;
public class Animal {
public void move() {
System.out.println("动物在移动");
}
}
package test001;
public class Cat extends Animal {
public void move() {
System.out.println("猫在移动");
}
// 子类特有方法
public void catchmouse() {
System.out.println("猫在抓老鼠");
}
}
package test001;
public class Bird extends Animal {
public void move() {
System.out.println("鸟在移动");
}
}
子类转父类,向上转型
package test001;
public class Test {
public static void main(String[] args) {
Animal A = new Cat();
// 子类转父类,向上转型
// 新建一个动物对象,这个对象是一只猫(合理)
A.move();
// Animal有move,可以调用move
// 但Animal没有catchmouse,所以不能调用
// 这个对象是一只猫,所以调用的move是调用的猫的move,注意区别
// 编译阶段+运行阶段
// 编译阶段认的是引用了Animal,这个过程是静态绑定(编译阶段绑定)
// 运行阶段,堆内存中真实创建的是cat对象,重写与否都是调用的是cat的
// 这个过程是动态绑定(运行阶段绑定)
}
}
如果希望A也能调用catchmouse方法,就需要强制类型转换/向下转型
当调用的方法父类型没有,就得强制转
Cat c2=(Cat)A;
c2.catchmouse();
但是由bird转到Animal,再从Animal转为cat,语法不会错,但是运行会出错
Animal a3=new Bird();
Cat c3=(Cat)a3;
c3.catchmouse();
ClassCastException类型转换异常,向下转型的时候常常发生
使用instanceof运算符,可以避免该异常
进行类型判断,养成好习惯
if(A instanceof Cat)
{
Cat c2=(Cat)A;
c2.catchmouse();
}
debug
双击行号,设置断点
右键进入debug模式
F6单步执行
方法如果没有,可以把鼠标移到方法上,直接create
多态实例
主人喂养猫猫狗狗
package test002;
public class Owner {
public void feed(Cat c){
c.eat();
//给狗添加一个eat
//要降低耦合
}
}
package test002;
public class Cat {
public void eat()
{
System.out.println("猫吃鱼");
}
}
package test002;
public class Dog {
public void eat()
{
System.out.println("狗吃肉!");
}
}
package test002;
public class Test {
public static void main(String[] args) {
Owner Zhang=new Owner();
Cat c=new Cat();
Dog d=new Dog();
Zhang.feed(c);
//Zhang.feed(d);
}
}
主人喂养猫,可以调用eat,但是如果还需要调用狗的eat,那就得重写整个程序。
所以最好写个宠物类,再来调用就行。
package test002;
public class Owner {
public void feed(Pet p){
p.eat();
//给狗添加一个eat
//要降低耦合
}
}
package test002;
public class Cat extends Pet{
public void eat()
{
System.out.println("猫吃鱼");
}
}
package test002;
public class Dog extends Pet{
public void eat()
{
System.out.println("狗吃肉!");
}
}
package test002;
public class Pet {
public void eat() {
}
}
package test002;
public class Test {
public static void main(String[] args) {
Owner Zhang = new Owner();
Cat c = new Cat();
Dog d = new Dog();
Zhang.feed(c);
Zhang.feed(d);
}
}
package test002;
public class Snake extends Pet {
public void eat()
{
System.out.println("蛇吃东西");
}
}
加一点也可以扩展到其他动物
final
final修饰的类不能被继承,修饰的方法不能被覆盖,修饰的变量一旦赋值,不能更改,
比如系统定义的String不能被继承
final指向某个对象后不能指向其他对象,但是所指向对象的内存是可以被修改的
package finalTest;
public class FinalTest {
public static void main(String[] args) {
String demo;
demo = "abcdaaaccd";
String demo2 = demo.replace("a", "b");
System.out.println(demo2);
}
}
final int age;
//直接就赋值为默认值了,并且绑定了不能修改,所以这个语句报错
final int age=10;
//必须手动赋值
或者写
final int num;
public FinalTest()
{this.num=200;
}
//因为不写构造方法也会有默认构造方法,构造方法里面赋值的话,执行顺序在final int num之前
类常量
常量定义的格式
public static final 类型 常量名=值
package finalTest;
public class FinalTest01 {
public static void main(String[] args) {
Chinese chi = new Chinese();
System.out.println(chi.Country);
}
}
class Chinese {
public static final String Country = "China";
// final修饰的实例不能变,这种变量一般和static联合用,被称为“常量”
}
static final
包(package)
一般写包名的命名规则
公司域名倒序+项目名+模块名+功能名
com.bupt.oa.user.service
全部小写,一个包对应一个目录
同一个包下,不用写包名
如果不是同一个包,那么写类名必须把前缀加上
com.bupt.oa.user.service.Test01
import
import用于导入其他类
import后面跟包名
导入之后就不用写包名了
package finalTest02;
import java.util.*;
//系统的包
public class FinalTest02 {
public static void main(String[] args) {
Date D=new Date();
System.out.println(D);
}
}
可以从需要导包的部分copy qualified name
protected
package finalTest02;
public class Test {
public static void main(String[] args) {
User u=new User();
System.out.println(u.i);
System.out.println(u.j);
}
}
package finalTest02;
public class User {
protected int i=20;
int j=10;
}
当某个数据只希望子类使用,使用protected
public | 公开的,任何位置都能访问 |
---|---|
protected | 同包,或者跨包,但作为子类 |
private | 表示私有的,只能在本类中访问 |
缺省 | 同包 |
结束时间:2020-10-19