多态:
1. 面向对象(封装 继承 多态)
2. 举例 :(学生类)
大学生类:小朱
(1)小朱是一名学生
(2)小朱是一名大学生
小朱是一个对象,但是具有两种身份
使用这两种身份时:
(1)其中子类大学类身份更加具体
(2)学生类身份比较抽象
转型 :
基本数据类型的转型:
1.强制转型:
int i = 1.2;// int i = (int)1.2;
double d = 1.2;int i = (int)d;
2.自动转型:
int i =1000;double d = i;
3.引用数据类型: 类 接口 数组
4.自动转型:
A a = new A();
B b = a;成立条件为: B 是A的父类
理解:一个学生是一个大学生?
不一定!
但一个大学生一定是一个学生!
子类创建对象,对象的地址一般会存在子类类型对应的对象变量名中(本质是c语言的指针)如:创建A类对象a
A a = new A();a是对象变量名
但实际上对象是内存中具体的一份数据体!
子类对象的引用地址 也可以存在一个父类类型的对象变量名中
A extends B | B b=a
子类继承父类的注意事项:
1.子类继承父类时,可以继承父类的属性和方法
2.子类还可以定义自己的属性和方法
3.子类还可以重写父类的方法
4.子类对象转型之后,调用时有无变化可以调用继承的方法,,如果继承的方法被子类重写了,那就调用子类重写的方法5.子类对象转型之后,不能调用子类独有的属性和方法
样例1:用Student类实现:
1.创建Student类:
public class Student {
String name;
int age;
public void setName(String name) {
this.name = name;
}
public void showInfo() {
System.out.println(name + " " + age);
}
public void read() {
System.out.println("Student read");
}
}
2.分别用UNStudent类,Midstudent类继承父类student,并重写父类中的方法:
class UNStudent extends Student {
// 子类还可以定义自己的属性和方法
int cet_4;
public void cetExam() {
cet_4 = 500;
System.out.println("UnStudent cetExam");
}
// 重写父类的方法
// 同时也会覆盖原本继承的
@Override
public void read() {
System.out.println("UnStudent read");
}
//
}
class MidStudent extends Student {
@Override
public void read() {
System.out.println("MidStudent read");
}
}
3.主函数测试:
class Manage {
//多态2: 同一个方法执行 执行了多种不同的结果
//主函数!传入学生对象
public static void studentRead(Student stu) {
stu.read();
}
}
class Main {
public static void main(String[] args) {
UNStudent unStu1 = new UNStudent();
Student stu1 = unStu1;
System.out.println(stu1);
System.out.println(unStu1);
// 此时 stu1 与 unStu1存储的内容是同一个对象的地址
unStu1.name = "qq";
unStu1.age = 20;
unStu1.cet_4 = 0;
// unStu1.id="";// 类中没有定义 无法编译
unStu1.setName("qq");
unStu1.read();
unStu1.cetExam();
unStu1.showInfo();
// 转型之后, 子类原本自己独有的属性和方法不能调用 继承的方法可以调用
stu1.name = "ww";
stu1.age = 25;
stu1.setName("ww");
stu1.read();// 转型之后还是调用重写的方法
stu1.showInfo();
unStu1.showInfo();
// 创建一个中学生对象
MidStudent midStu1 = new MidStudent();
UNStudent unStu2 = new UNStudent();
// 学生读书活动 需要的参数是 Student类型
Manage.studentRead(midStu1);
Manage.studentRead(unStu2);
//与下面效果是相同的
Student stu2 = unStu2;
Student stu3 = midStu1;
Manage.studentRead(stu2);
Manage.studentRead(stu3);
}
}
注意,manage类定义了静态方法,调用时直接类名加函数名,其次,传入参数类型为Student的子类对象时,进行自动向上转型,调用该类型子类重写父类的方法!
运行结果如下:
同理,可以看看样例2,与样例1的形式差不多:
public class User {
String name;
String password;
int age;
boolean isVip;
boolean isAdmin;
boolean isUser;
public void home() {
System.out.println("欢迎登录XX系统");
System.out.println("这里是您个人主页,用户等级:普通用户");
}
}
class AdminUser extends User {
public void home() {
System.out.println("欢迎登录xx系统后台");
System.out.println("这里是您个人主页,用户等级:管理员");
}
}
class VIPUser extends User {
@Override
public void home() {
System.out.println("欢迎登录xx系统后台");
System.out.println("这里是您个人主页,用户等级:VIP");
}
}
class SystemMain {
public static void login(User user, String pwdIn) {
if (user.password.equals(pwdIn)) {
user.home();
}
}
public static void main(String[] args) {
User user = new User();
user.password = "123";
AdminUser aduser = new AdminUser();
aduser.password = "1234";
VIPUser vipuser = new VIPUser();
vipuser.password = "12345";
// 调用相同的方法 出来不同的结果
// user.login("123");
// aduser.login("123");
// vipuser.login("123");
login(user, "123");
login(aduser, "1234");
login(vipuser, "12345");
User[] users = new User[3];
users[0] = user;
users[1] = aduser;
users[2] = vipuser;
for (int i = 0; i < 3; i++) {
User u = users[i];
login(u,"123");
}
}
}
运行结果: