10. this调用构造器、package关键字的使用、import关键字的使用、OPP的特征二:继承性、4种权限修饰符的演示、方法的重写

1.this调用构造器

this 可以用来调用:属性、方法、构造器
1. this调用属性、方法
2. this调用构造器
  ① 格式: this(参数列表)
  ② this调用构造器的操作,只能声明在构造器中。表示调用当前类中的指定的重载的其他的构造器
  ③ this(参数列表) 只能声明在构造器的首行
  ④ 一个构造器中,最多只能声明一个"this(参数列表)"
  ⑤ 如果一个类中声明有n个构造器,则最多有 n - 1个构造器中使用了"this(参数列表)"
  • 代码举例
public class ThisTest {
   public static void main(String[] args) {
       User u1 = new User("Tom");
       User u2 = new User("Jerry",12);
       u2.show();
   }
}

class User{
   private String name;
   private int age;

   public User() {
       //初始化User,需要做10件事情
//        this("tom");
       System.out.println("User()...");
   }

   public User(String name) {
       this();//调用User类中空参的构造器
       this.name = name;
   }

   public User(String name, int age) {
//        this();
       this(name);
       //this.name = name;
       this.age = age;
   }

   public void setName(String name){
       this.name = name;
   }
   public String getName(){
//        return this.name;
       return name;
   }

   public int getAge() {
       return age;
   }

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

   public void show(){
       System.out.println("name = " + this.name + ", age = " + this.age);

       this.info();
   }
   public void info(){
       System.out.println("我是一个user");
   }
}
  • 练习
public class Boy {
   private String name;
   private int age;

   public Boy() {
   }

   public Boy(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 shout(){
       if(this.age >= 22){
           System.out.println("我已经到了法定可以结婚的年龄");
       }else{
           System.out.println("先谈谈恋爱~~");
       }
   }

   public void marry(Girl girl){
       System.out.println("我是" + name + ",我想娶" + girl.getName());
   }
}


public class Girl {
   private String name;
   private int age;

   public Girl() {
   }

   public Girl(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 marry(Boy boy){
       System.out.println("我是" + name + ",我想嫁给" + boy.getName());
//        boy.marry(new Girl());

       boy.marry(this);
   }

   /**
    * 比较两个对象大小的方法
    * @param girl
    * @return 正数:当前对象大; 0:一样大; 负数:形参对象大
    */
   public int compare(Girl girl){
       if(this.age > girl.age){
           return 1;
       }else if(this.age == girl.age){
           return 0;
       }else{
           return -1;
       }
   }
}


public class BoyGirlTest {
   public static void main(String[] args) {
       Boy boy = new Boy("梁山伯",23);
       boy.shout();

       Girl girl = new Girl("祝英台",20);
       girl.marry(boy);

       Girl girl1 = new Girl("朱丽叶",21);

       System.out.println(girl.compare(girl1));
   }
}

2.package关键字的使用

package: 包
> 便于针对于大量创建的类进行统一的管理。
> 包,属于标识符,遵循标识符命名的规则、规范(xxxyyyzzz)、“见名知意”
> 包,声明在Java源文件中的首行。
> 包的声明中每"."一次,代表一层文件目录
  • jdk常用的包
    在这里插入图片描述

3.import关键字的使用

 * 1. import:导入
 *   > 我们在现有的java源文件中,可以导入其他源文件中声明的结构:类、接口
 *   > import结构声明在包的声明和类的声明之间。如果多个import语句,则并列声明
 *   > 导入的类或接口等,需要写明其完整的结构:xxx.yyy.*。
 *   > 一方面,针对于java提供好的api,如果使用的结构来自于java.lang包,则可以声明import导入。
 *     如果来自于其他的包,则必须显式的导入
 *   > 另一方面,如果导入的其他源文件中的结构,与当前源文件在同一个包下,则可以声明省略显式的导入
 *   > 如果有多条import 导入结构,则先后声明即可。没有先后顺序之说。
 *   > 举例:使用import java.util.* 可以表示将util包下的所有类或接口进行导入。
 *   > 如果我们导入指定a包下的*,则a包的子包中的结构是不包含在导入内。如果需要,还得显式导入
 *   > 如果在文件中使用了不同包下的同名的类,则至少有一个类需要使用全类名的方式表示。比如:两个Date
 *   > import static :显式的导入指定的类或接口中的静态结构:静态属性、静态方法
 * 2. 拓展:
 *    同一个包下不能定义同名的类
 *    不同包下,可以定义同名的类

4.面向对象的特征二:继承性

  • 理解
    在这里插入图片描述
1. 继承性的好处:
 * > 继承的出现减少了代码冗余,提高了代码的复用性。
 * > 继承的出现,更有利于功能的扩展。
 * > 继承的出现让类与类之间产生了关系,提供了多态的前提。
  • 相关知识
* class A extends B {}
*    A :子类、SubClass
*    B :父类、SuperClass、超类、基类
*  * 2.
*   2.1
*  当子类继承父类以后,就获取了父类中声明的结构:属性、方法。即使父类中的结构声明的权限较小(比如:private),
*  我们也认为子类通过继承的方式,获取了父类中权限较小的结构。只不过由于权限的影响,不能直接调用而已。
*  2.2
*  子类在继承父类之后,还可以定义自己特有的结构:属性、方法。也就是说,子类相较于父类,功能更强大、丰富
*  * 3. 说明
*  ① java中的类的继承性只能是单继承的。但是,一个父类可以声明有多个子类
*  ② 子类可以间接的继承于父类的父类。(直接父类、间接父类)
*  ③ 子父类是一对相对的概念
*  ④ 当没有显式的声明一个类A的父类时,默认此类A继承于java.lang.Object类
*  ⑤ 子类继承父类以后,创建子类对象,在创建的堆空间的对象实体中,是包含直接父类及所间接父类中声明的所的属性的。
* 只不过由于封装的影响,导致子类对象可能不能直接调用此属性罢了。如果需要调用,可以给私有的属性,设置公共的getter()或 setter()方法。
*     > 任何一个Java类都继承于java.lang.Object类?yes!

在这里插入图片描述

  • 代码演示
public class Creature{//生物
    public void breath(){
        System.out.println("呼吸");
    }
}

public class Person extends Creature{ //人类
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person() {
    }
    public void eat(){
        System.out.println("吃饭");
        sleep();
    }
    private void sleep(){
        System.out.println("睡觉");
    }
    public void think(String thing){
        System.out.println("思考:" + thing);
    }

    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 info(){
        System.out.println("name = " + name +",age = " + age);
    }
}


public class Student extends Person{

//    String name;
//    int age;

    String major;//专业

    public Student(String name, int age) {
//        this.name = name;
//        this.age = age;
        setName(name);
        setAge(age);
    }

    public Student() {

    }

//    public void eat(){
//        System.out.println("吃饭");
//    }
//    public void sleep(){
//        System.out.println("睡觉");
//    }
//    public void think(String thing){
//        System.out.println("思考:" + thing);
//    }

    public void study(){
        System.out.println("学习");
    }
}
  • 测试类
public class ExtendsTest {
   public static void main(String[] args) {
       Person p1 = new Person();
//        p1.name = "Tom";
       p1.setName("Tom");
       p1.eat();
       p1.think("晚上吃什么?");

       Student s1 = new Student();
//        s1.name = "Jerry";
       s1.setName("Jerry");
       s1.eat();
       s1.think("期末考试什么时候?");

       s1.info();

       s1.breath();

       System.out.println("############");
       Creature c = new Creature();
       c.breath();
//        c.study();//父类不能调用子类的结构
       c.toString();//c调用了父类中的方法
       System.out.println(c.getClass().getSuperclass());
   }
}
  • 课后练习
    在这里插入图片描述
public class ManKind {
    private int sex;
    private int salary;

    public void manOrWoman(){
        if(sex == 1){
            System.out.println("Man");
        }else if(sex == 0){
            System.out.println("Woman");
        }
    }

    public void employeed(){
        if(salary == 0){
            System.out.println("no Job!");
        }else{
            System.out.println("Job!");
        }
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }
}

package com.atguigu.exer1;

/**
 * 定义类Kids继承ManKind,并包括
 * 成员变量int yearsOld;
 * 方法printAge()打印yearsOld的值。
 *
 * 修改:在Kids中重新定义employeed()方法,
 * 覆盖父类ManKind中定义的employeed()方法,输出“Kids should study and no job.”
 *
 */
public class Kids extends ManKind{
    private int yearsOld;// 年龄

    public void printAge(){
        System.out.println("I am " + yearsOld + " years old.");
    }

    public int getYearsOld() {
        return yearsOld;
    }

    public void setYearsOld(int yearsOld) {
        this.yearsOld = yearsOld;
    }

}

package com.atguigu.exer1;

/**
 * 定义类KidsTest,在类的main方法中实例化Kids的对象someKid,用该对象访问其父类的成员变量及方法。
 */
public class KidsTest {
    public static void main(String[] args) {

        Kids someKid = new Kids();
        //调用父类的结构
        someKid.setSex(1);
//        someKid.setSalary(0);

        someKid.employeed();
        someKid.manOrWoman();

        //调用子类自己声明的结构
        someKid.setYearsOld(12);
        someKid.printAge();


    }
}
  • 练习2
    在这里插入图片描述
public class Circle {
    private double radius ;//半径

    public Circle(){
        System.out.println("Circle()....");
        radius = 1;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
    //计算圆的面积
    public double findArea(){
        return Math.PI * radius * radius;
    }
}


public class Cylinder extends Circle{//圆柱类
    private double length;//高度

    public Cylinder(){
        length = 1;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }

    public double findVolume(){//返回圆柱的体积
//        return Math.PI * getRadius() * getRadius() * length;
        return findArea() * length;
    }


}


/**
 * 在CylinderTest类中创建Cylinder类的对象,设置圆柱的底面半径和高,并输出圆柱的体积
 *
 */
public class CylinderTest {
    public static void main(String[] args) {
        Cylinder cy = new Cylinder();

//        cy.setRadius(3.4);
//        cy.setLength(1.2);

        System.out.println("圆柱的体积为:" + cy.findVolume());
        System.out.println("圆柱的底面积为:" + cy.findArea());
    }
}

5.四种权限修饰符的演示

在这里插入图片描述

6.方法的重写

  • 为什么要重写
测试方法的重写(override / overwrite)
1. 举例:
class Account{ //账户
 	private double balance = 100;//余额
 	public void withdraw(double amt){} //取钱
}
	class CheckingAccount extends Account{//信用卡账户
 	private double protectedInit = 5000;//透支额度
}
2.诉求:子类继承父类以后,从父类继承过来的方法不适用子类,则子类可以对父类继承来的方法进行覆盖、复写操作。那这个过程,就称为方法的重写。

  1. 方法重写的细节:
    权限修饰符 返回值类型 方法名 (形参列表){
    方法体
    }

① 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符。

  •  特别的:子类不能重写父类中声明为private权限的方法。
    

② 返回值类型 :

  • 如果父类被重写的方法的返回值类型为void,则子类重写的方法的返回值类型也必须为void
    
  • 如果父类被重写的方法的返回值类型是基本数据类型,则子类重写的方法的返回值类型必须为相同的基本数据类型
    
  • 如果父类被重写的方法的返回值类型是引用数据类型,则子类重写的方法的返回值类型可以与父类的方法的返回值类型相同或是其返回值类型的子类
    

③ 子类重写的方法的方法名、形参列表与父类被重写的方法的方法名、形参列表相同

④ 子类重写的方法的方法体一定与父类被重写的方法的方法体不同

总结:实际开发中,子类重写父类的方法的整体声明都相同。

子父类中同名同参数的方法要么都声明为static,要么都不能声明为static(认为要重写)

  1. 当子类重写了父类的方法之后,通过子类的对象调用此方法时,执行的是子类重写父类的方法。
    */

面试题:区分方法的重载和重写?

  • 代码演示
public class OverWriteTest {
    public static void main(String[] args) {
        CheckingAccount acct = new CheckingAccount();
        acct.withdraw(300);
        System.out.println("账户余额为:" + acct.getBalance());
        System.out.println("账户透支额度为:" + acct.getProtectedInit());
    }
}

class Account{ //账户
    private double balance = 100;//余额
    public void withdraw(double amt){ //取钱  父类被重写的方法
        if(amt <= balance){
            balance -= amt;
            System.out.println("成功取出:" + amt);
        }else{
            System.out.println("取款失败");
        }
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public long methodA(){
        return 0L;
    }

    public String methodB(){

        return null;
    }

}

class CheckingAccount extends Account {//信用卡账户
    private double protectedInit = 5000;//透支额度

    public void withdraw(double amt){ //子类重写的方法
        if(amt <= getBalance()){
            setBalance(getBalance() - amt);
            System.out.println("成功取出:" + amt);
        }else if(amt <= getBalance() + protectedInit){
            protectedInit -= (amt - getBalance());
            setBalance(0);
            System.out.println("使用了信用资金。成功取出:" + amt);
        }else{
            System.out.println("取款失败");
        }
    }

    public double getProtectedInit() {
        return protectedInit;
    }

    public long methodA(){
        return 0;
    }

    @Override
    public String methodB() {
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值