Java面向对象特征二-继承性

47 篇文章 1 订阅

Java继承性

b站学习视频以及笔记-尚硅谷_Java零基础教程

java入门必备-适合初学者的全套完整版教程(宋红康主讲)

一. 为什么要有类的继承性?(继承性的好处)

  • ① 减少了代码的冗余,提高了代码的复用性

  • ② 便于功能的扩展

  • ③ 为之后多态性的使用,提供了前提

图示:

image-20201107141347682

二. 继承性的格式:

class A extends B{}

  • A:子类、派生类、subclass
  • B:父类、超类、基类、superclass

三. 子类继承父类以后有哪些不同?

  1. 体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。当父类属性为private修饰符时,子类是不能直接调用的。此时我们需要在父类中实现公有get方法,然后再在子类中去调用父类的get方法。
class Person{
	private int score;//私有变量,此处也体验了封装性

	//公有方法
	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}
}

class Student extends Person{
	
	
	public void info(){
		System.out.println(Score);//编译出错,score是private类型不能在子类直接引用
	}
	
	public void show(){
		System.out.println(getScore());//调用父类的公有方法getScore,可以获取sore的值
	}

}
  1. 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。
  • 特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私的结构。只因为封装性的影响,使得子类不能直接调用父类的结构而已。
  • 子类和父类的关系,不同于子集和集合的关系。
  • extends:延展、扩展

四. Java中继承性的说明

  1. 一个类可以被多个子类继承。

  2. Java中类的单继承性:一个类只能有一个父类

  3. 子父类是相对的概念。

  4. 子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类

  5. 子类继承父类以后,就获取了直接父类以及所间接父类中声明的属性和方法

图示:

image-20201107145335786

五. java.lang.Object类的理解

  1. 如果我们没显式的声明一个类的父类的话,则此类继承于java.lang.Object类
  2. 所的java类(除java.lang.Object类之外都直接或间接的继承于java.lang.Object类
  3. 意味着,所的java类具有java.lang.Object类声明的功能。

六. 代码实现

父类Creature
public class Creature {
	
	//定义一个呼吸方法
	public void breath(){
		System.out.println("呼吸");
	}
	
}

子类Person
public class Person extends Creature{
	
	String name;//名字
	private int age;//年龄
	
	//无参构造器
	public Person(){
		
	}
	
	//有参构造器
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	
	
	public void eat(){
		System.out.println("吃饭");
		sleep();//同一类方法中调用其他方法
	}
	
	private void sleep(){
		System.out.println("睡觉");
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	
}

子类Student
public class Student extends Person{
	
//	String name;//继承了父类已有的属性后,就不用在子类里再去实现了
//	int age;
	String major;
	
	public Student(){
		
	}
	public Student(String name,int age,String major){
		this.name = name;
//		this.age = age;//初始化年龄
		setAge(age);//调用父类方法给年龄初始化
		this.major = major;//主修
	}
//	public void eat(){继承了父类已有的方法后,就不用在子类里再去实现了
//		System.out.println("吃饭");
//	}
//	
//	public void sleep(){
//		System.out.println("睡觉");
//	}
	
	public String getMajor() {
		return major;
	}
	public void setMajor(String major) {
		this.major = major;
	}
	public void study(){
		System.out.println("学习");
	}
	
	public void show(){
		System.out.println("name:" + name + ",age:" + getAge()+",major:"+major);
	}
	
}


测试类ExtendsTest

public class ExtendsTest {
	public static void main(String[] args) {
		
		Person p1 = new Person();
//		p1.age = 1;
		p1.eat();
		System.out.println("*****************");
		
		Student s1 = new Student();//调用无参构造方法
		s1.eat();
//		s1.sleep();
		s1.name = "Tom";//初始化name为Tom
		s1.setAge(10);//年龄设为10
		System.out.println(s1.getAge());//输出对象s1的年龄
		s1.show();//调用父类的show方法,注意上面只给对象s1初始化了年龄和名字,没初始化主修课程,所以课程值为null
		
		Student s2 = new Student("小涛",20,"软件工程");//调用无参构造方法
		s2.show();
		
		s1.breath();//这里是调用父类的父类的方法
		
		
		Creature c = new Creature();//c为父类的父类创建的对象c
		System.out.println(c.toString());
		//此处的toString方法是Object类的方法(Object是除了它本身所有类的父类,java中已经帮我们写好		//的方法),Ctrl加鼠标单击方法可以查看object类中toSring方法
//可以看到它写好的方法为:  public String toString() {return getClass().getName() + "@" + //Integer.toHexString(hashCode());}返回值为类名和对象地址

	}
}

运行结果:

image-20201107153535546

七. 作业:

image-20201107154559982

public class Account {
	
/*	id 账号
	balance 余额
	annuallnterestRate 年利率*/
	private int id;
	private double balance;
	private double annualInterestRate;
		
	public Account(int id,double balance,double annualInterestRate){
		super();
		this.id = id;
		this.balance = balance;
		this.annualInterestRate = 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 double getMonthlyInterest(){	
			return annualInterestRate / 12;
		}
		
	//取钱
	public void withdraw(double amount){
		if (balance>=amount){
			balance = balance - amount;
			System.out.println("成功取出:"+amount);
			return;
		}else{
			System.out.println("余额不足,取款失败");
		}
	}
	
	
	//存钱
	public void deposit(double amount){
		if(amount>0)
		balance = balance +amount;
		System.out.println("成功存入:"+amount);
	}
	
}

image-20201107154647547

public class Customer {
    private String firstName;
    private String lastName;
    private Account account;

    public Account getAccount() {
        return account;
    }
    public void setAccount(Account account) {
        this.account = account;
    }

    //	构造器
    public Customer(String f,String l){
        firstName = f;
        lastName = l;
    }
    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }
}

image-20201107155003789

  • 写一个用户程序测试Account类。在用户程序中,
  • 创建一个账号为1000、余额为2000、年利率1.23%的Account对象。
  • 使用withdraw方法提款30000元,并打印余额。
  • 使用deposit方法存款100元,
  • 使用withdraw方法提款960元,再使用withdraw方法提款2000元,然后打印余额和月利率。


public class AccountTest {
	
public static void main(String[] args) {
	Customer person = new Customer("Jian","Smith");
	
	Account personal = new Account(1000,2000,1.23);
	
	person.setAccount(personal);
	person.getAccount().deposit(100);
	person.getAccount().withdraw(960);
	person.getAccount().withdraw(2000);
	System.out.println("Customer ["+person.getFirstName()+","+person.getLastName()+"] has a account:id is "+personal.getId()+",annualInterestRate is "+
	personal.getAnnualInterestRate()+"%,balance is "+personal.getBalance() );
	}
}

输出结果:

  • 创建Account类的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。
  • 在CheckAccount类中重写withdraw方法,其算法如下:
  • 如果(取款金额<账户余额,
    可直接取款
    如果(取款金额>账户余额,
    计算需要透支的额度
    判断可透支额overdraft是否足够支付本次透支需要,如果可以
    将账户余额修改为0,冲减可透支金额
    如果不可以
    提示用户超过可透支额的限额

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 void setOverdraft(double overdraft)
    {
        this.overdraft = overdraft;
    }

    public double getOverdraft(){
        return overdraft;
    }

    //取钱
    public void withdraw(double amount){
        if (getBalance()>=amount){//余额足够消费
    //			getBalance() -= amount;
    //			方式一:
    //			setBalance(getBalance()-amount);
    //			方式二
            super.withdraw(amount);
        }else if(overdraft > amount - getBalance()){
            overdraft -= (amount - getBalance());
    //			setBalance(0);
            super.withdraw(getBalance());
        }else{
            System.out.println("超出额度!");
        }
    }
}
	
  • 写一个用户程序测试CheckAccount类。
  • 在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%,可透支限额为5000元的CheckAccount对象。
  • 使用withdraw方法提款5000元,并打印账户余额和可透支额。
  • 再使用withdraw方法提款18000元,并打印账户余额和可透支额。
  • 再使用withdraw方法提款3000元,并打印账户余额和可透支额。

public class CheckAccountTest {
public static void main(String[] args) {
        CheckAccount a = new CheckAccount(1122, 20000, 4.5,5000);
        a.withdraw(5000);
        System.out.println("账户余额为:"+a.getBalance());
        System.out.println("可透支额为:"+a.getOverdraft());
        a.withdraw(18000);
        System.out.println("账户余额为:"+a.getBalance());
        System.out.println("可透支额为:"+a.getOverdraft());
        a.withdraw(3000);
        System.out.println("账户余额为:"+a.getBalance());
        System.out.println("可透支额为:"+a.getOverdraft());
	}
}

输出结果:
image-20201107160819064

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值