子类对象实例化的全过程
1.从结果上来看:
子类继承父类以后,就获取了父类中声明的属性和方法。
创建子类的对象,在堆空间中,就会加载所有父类总声明的属性。
2.从过程上来看:
当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器。。。直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有父类中的结构,子类对象才可以考虑进行调用。
明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new的子类对象。
继承性的练习:
写一个用户程序测试Account类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%的Account对象,使用withdrew方法提款30000元,并打印余额,再使用withdrew方法提款2500元,使用deposit方法存款3000元,然后打印余额和月利率。
public class AccountTest {
public static void main(String[] args){
Account acct = new Account(1122,20000,0.045);
acct.withdraw(30000);
System.out.println("您的账号余额为:"+ acct.getBalance());
acct.withdraw(2500);
System.out.println("您的账号余额为:"+ acct.getBalance());
acct.deposit(3000);
System.out.println("您的账号余额为:"+ acct.getBalance());
System.out.println("月利率为:" + (acct.getMonthlyInterest() * 100) + "%");
}
}
public class Account {
private int id;// 账号
private double balance;//余额
private double annualInterestRate;//构造器
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getAnnualInterestRate() {
return annualInterestRate;
}
public void setAnnualInterestRate(double annualInterestRate) {
this.annualInterestRate = annualInterestRate;
}
public Account(int id, double balance, double annualInterestRate){
super();
this.id = id;
this.balance = balance;
this.annualInterestRate = annualInterestRate;
}
//返回月利率
public double getMonthlyInterest(){
return annualInterestRate /12;
}
//取钱
public void withdraw(double amount){
if(balance >= amount){
balance -= amount;
return;
}
System.out.println("余额不足");
}
//存钱
public void deposit(double amount){
if(amount > 0){
balance += amount;
}
}
}
创建Account类的一个子类CheckAccount代表可透支的账户,该账号中定义一个属性overdraft代表可透支限额。
public class CheckAccount extends Account{
private double overdraft;
public CheckAccount(int id,double balance,double annualInterestRate,double overdraft){
super(id,balance,annualInterestRate);
this.overdraft = overdraft;
}
public double getOverdraft() {
return overdraft;
}
@Override
public void withdraw(double amount) {
if(getBalance() >= amount){//余额足够时
super.withdraw(amount);
}else if(overdraft >= amount - getBalance()){//透支额度+余额足够消费
overdraft -= (amount - getBalance());
setBalance(0);
}else {
System.out.println("超过可透支限额");
}
}
}
写一个用户程序测试CheckAccount类。
public class CheckAccountTest {
public static void main(String[] args){
CheckAccount acct = new CheckAccount(1122,20000,0.045,5000);
acct.withdraw(5000);
System.out.println("您的账号余额为:" + acct.getBalance());
System.out.println("您的可透支额度为:" + acct.getOverdraft());
acct.withdraw(18000);
System.out.println("您的账号余额为:" + acct.getBalance());
System.out.println("您的可透支额度为:" + acct.getOverdraft());
acct.withdraw(3000);
System.out.println("您的账号余额为:" + acct.getBalance());
System.out.println("您的可透支额度为:" + acct.getOverdraft());
}
}
面向对象的特征之三:多态性
1.理解多态性:可以理解为一个事物的多种形态
2.何为多态性
对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
3.多态的使用:当调用子类同名同参数的方法时,实际执行的是子类重写父类的方法---虚拟方法调用
虚拟方法调用:有了对象的多态性以后,我们再编译期,只能调用父类中声明的方法,但运行期,我们实际执行的是子类重写父类的方法。
总结:编译看左边;运行,看右边。
4.多态性的使用前提:
4.1类的继承关系
4.2要有方法的重写
5.对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)
public class Person {
String name;
int age;
public void eat(){
System.out.println("人:吃饭");
}
public void walk(){
System.out.println("人:走路");
}
}
public class Man extends Person{
boolean isSmoking;
public void earnMoney(){
System.out.println("男人负责挣钱养家");
}
public void eat(){
System.out.println("男人多吃肉,长肌肉");
}
public void walk(){
System.out.println("男人霸气的走路");
}
}
public class Woman extends Person{
boolean isBeauty;
public void goShopping(){
System.out.println("女人喜欢购物");
}
public void eat(){
System.out.println("女人少吃,为了减肥");
}
public void walk(){
System.out.println("女人窈窕的走路");
}
}
public class PersonTest {
public static void main(String[] args){
Person p1 = new Person();
p1.eat();
Man man = new Man();
man.eat();
man.age = 25;
man.earnMoney();
//对象的多态性
Person p2 = new Man();
// Person p3 = new Man();
p2.eat();
p2.walk();
}
}
多态性案例:
public class AnimalTest {
public static void main(String[] args){
AnimalTest test = new AnimalTest();
test.func(new Dog());
test.func(new Cat());
}
public void func(Animal animal){
animal.eat();
animal.shout();
}
}
class Animal{
public void eat(){
System.out.println("动物:进食");
}
public void shout(){
System.out.println("动物:叫");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void shout(){
System.out.println("汪!汪!汪");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void shout(){
System.out.println("喵喵喵");
}
}
总结:今天学习了子类对象实例化的全过程、继承和super的课后练习、多态性的使用、多态性使用举例、多态性不适用于属性、虚拟方法调用的再理解。
明日计划:明天复习着两天学习的内容。