Java短期班07

一、私有成员变量的访问和修改

重点来看数据的保护:
    于是对于私有成员变量的访问,提供了两种方法,专门供外界来访问一个对象的私有成员变量
    public get: 获取某一个成员变量的值
    public set: 修改某一个成员变量的值
    但是, 要注意,一个类中可以定义多个私有成员变量,而每一个成员变量,都对应一个get和set方法,为了表名
    get和set和,它们所针对的那个成员变量的对应关系,有以下命名规则
    成员变量名叫: xxx
    getXxx
    setXxx


     get,set方法带来的好处:
    1. 通过get,set,可以访问对象的私有成员变量值
    2. 通过get,set方法,完成对成员变量访问的读,写分离
    3. 正式因为,外部只能通过get,set方法来访问私有成员变量, 可以以这种方式控制外部,对成员变量值访问


   给对象成员变量赋初值:
1. 创建对象
   对象名.成员变量1 = 值1
   对象名.成员变量2 = 值2
   ...
   对象名.成员变量n = 值n
   对于私有成员,以上方式,就失效了
   对象名.setXxx(值)

   无参构造 + set方法给对象成员变量值手动赋初值

2. 利用带参的构造方法
package com.cspratice.Object02;

public class test {

    public static void main(String[] args) {
        String name = "zhangsan";
        Student student = new Student(name, 17, 1222);
//      System.out.println(student.name);//无法访问私有成员变量
//        name.method();//无法访问私有成员方法
        System.out.println(student.getAge());//访问私有成员变量
        student.setAge(17);//修改私有成员变量
        System.out.println(student.getAge());


    }
}

class Student{

    private String name;
    private int age;
    private int num;

    public Student(String name , int age , int num ) {//构造方法
        this.name = name;
        this.age = age;
        this.num = num;
    }

    private void method(){
        System.out.println("私有成员方法");
    }

    //alt + insert 快捷键

//得到Age
    public int getAge() {
        return age;
    }
//修改Age属性
    public void setAge(int age) {
        if (age > 130 || age < 0) {//可以防止输入不合法
            System.out.println("输入不合法");
            return;
        }
        this.age = age;
    }

}

二、继承

1、

/*
        继承概述
        Java中的继承和我们现实生活中的“继承”的含义基本类似,但是含义更广。
        1.简单来说都可以表示“不劳而获”
        2.类型之间“is a”的关系
          a. 一种类型(类) 继承 另外一种类型(类)
              子类             父类
          b. 从数据类型,可以把子类类型,当做父类类型
              从数据类型的角度,数据类型:一个数据集合和基于这个数据集合的一组操作
              当子类继承父类,子类拥有了父类中定义的成员(父类中的数据集和基于数据集的操作)

          c. 一个老师对象 是 一个人

         被继承的类称之为父类(基类或超类),继承其他类的类称之为子类(派生类)
         子类可以通过继承机制,不写任何额外代码就可以拥有父类的“所有”成员。

         继承的语法
            class 子类名 extends 父类名 {}
 */
public class Demo1Defination {

    public static void main(String[] args) {
        // 类型之间的"is a"
        // 一个老师 是 一个人
        Human human = new Teacher();
    }
}

class Human {
    String name;
}
// 继承别人的类,称之为子类,派生类
// 被继承的类,称之为父类,超类或基类
class Teacher extends Human {

}

2. 

继承的注意事项:
    子类只能访问父类所有非私有的成员(成员方法和成员变量)
    子类不能继承父类的构造方法  
    Java继承的特点:在Java中只能实现单重继承。

3.隐藏问题

a.成员变量的隐藏问题

 父类成员变量(field)的隐藏:
       如果,在子类中,定义了和父类同名的成员变量
        a. 在子类类体中,通过同名成员变量的变量名,访问到的是,子类中定义的同名成员变量值
           看起来,就好像父类成员变量,在子类中,被隐藏起来了
        b. 注意: 在父类方法的方法体中,通过变量名访问同名成员变量的值访问到的是,父类中定义的成员变量值

  1. 在子类中是否可以定义和父类同名的成员变量? 可以

  2. 如果可以,那么在子类中访问这个同名变量,
     究竟访问到的是父类对象中的值,还是子类对象中的值? 子类中定义的同名成员变量值
     如果在父类中访问呢? 父类中定义的同名成员变量值

  3. 是否可以在子类对象中,同时访问到子类对象和父类对象中的同名成员变量的值?
     可以,利用super关键字,可以在子类中,访问到继承自父类的成员变量值

 在父类子类中,如果定义了同名成员变量,记住以下结论:
1. 如果在方法体中,通过同名成员的变量名,访问父类和子类定义的同名成员变量值
   a. 如果是在父类的方法中,访问同名成员变量,访问到的就是父类的成员变量值
   b. 如果实在子类的方法中,访问同名成员变量,访问到的就是子类成员变量的值

2. 在子类对象上,对象.的方式来访问成员变量的值,访问到的是子类中定义的同名成员变量值
public class test2 {
    public static void main(String[] args){
        B b = new B();
        b.Acess2();//20
        b.Acess1();//10
        b.allAcess();//10 20
        System.out.println(b.num);//20

    }
}

class A{
    int num = 10;
    public void Acess1(){
        System.out.println("1="+num);
    }
}

class B extends A{
    int num = 20;
    public void Acess2(){
        System.out.println("2= "+num);
    }

    public void allAcess(){
        System.out.println("all = "+super.num);
        System.out.println(num);
    }
}

b.方法覆盖

 父类方法的覆盖问题:
    1. 子类中能否定义和父类一模一样的方法?  可以

    2. 如果可以,那么在子类对象中访问这个一模一样 的方法,
       究竟访问到的是父类对象中的方法,还是子类对象中的方法? 访问的是子类定义的方法
       如果在父类中访问呢? 访问到的是还是子类中定义的一摸一样的方法

    3. 是否可以在子类对象中,同时访问到子类对象和父类对象中的同名成员方法?
       可以,使用super.方法的形式,在子类中调用父类中定义的一模一样的方法

    解释一下,在jvm中所要确定索要执行的方法(在子类对象上调用方法)

  jvm是如何确定执行哪个方法的?
 a. 首先,会在子类对象对应的子类中去找,要执行的方法,如果找到,就直接执行。
 b. 如果在子类中,没有找到,要执行的目标方法,才会在父类中这个方法。

所以,基于以上的方法执行的,搜索策略:所以因为在子类对象上,调用那个子类和父类一模一样的方法,
所以,永远先找到子类中定义的那个,一模一样的方法并执行。

发生方法覆盖的条件: 必须是在父类子类中定义一模一样的方法?

1. 访问权限
    a. 子类方法的访问权限,不一定要和父类方法的访问权限一样
    b. 子类方法的访问权限 >= 父类方法的访问权限

2. 方法返回值
   a. 子类方法的方法返回值和父类方法的返回值相同
   b. 子类方法的返回值可以不和父类方法的返回值相同,
      子类方法的返回值类型 是 父类方法返回值类型的子类类型

3. 方法签名:
    子类方法需要和父类方法相同
注意事项:
  1.父类中私有方法不能被覆盖
  2.静态方法不能被覆盖!!

  可以利用@OVerride注解,来测试是否发生方法覆盖:
  一旦我们给一个方法加@Override注解,就相当于在告诉编译,该方法一定覆盖父类的方法

4.子类对象初始化问题

/*
     对于一个子类对象而言,其内存中的数据,分成了两部分:
    1. 从父类中,继承下来成员变量的值
    2. 子类中,自己定义的成员变量的值

    子类对象的初始化问题(子类中成员变量(两部分)赋予初值先后顺序)
    这两部分数据,在给他们赋初值的时候,谁先赋初值谁后赋初值(谁先初始化值,谁后初始化值)?
    java语言的结论是,一定是 先 初始化子类对象中,继承的父类变量的值,后,初始化子类对象中,
    子类自己定义的成员变量值
    先父后子

    为什么一定要先父后子:
    a. 从直觉的角度,类比于现实生活,如果要继承父辈的财产,父辈得先存在,有一定的财富积累
    b. 在实际开发中,我们子类成员变量的初值,依赖于父类成员变量值


    如何实现,在子类对象中,先父后子的,成员变量值的初始化顺序呢?
    核心思路:
    1. 首先,构造方法本身的功能,就是初始化对象成员变量值的
    2. 所以,显然,对我们只需要保证,父类的构造方法,先于子类的构造方法运行
    3. 如何让父类构造方法,先于子类构造方法执行(在子类的构造方法的,第一条语句的位置,先去调用父类)


    在子类对象初始化的过程中,保证先父后子的子类对象的初始化顺序:
    1. 子类对象的隐式初始化方式(jvm来自动保证父类构造方法自动保证)
    2. 子类对象的显示初始化方式(coder,通过写代码的方式保证,父类构造方法先执行)


 */
public class Demo1Introduction {

    public static void main(String[] args) {
        Student student = new Student();

        // 访问继承父类的成员变量值
        System.out.println(student.name);

        // 访问子类自己定义的成员变量
        System.out.println(student.studentId);
    }
}

class Person {
    // 姓名
    String name;

    int fatherI;

    public void eat() {
        System.out.println("吃饭ing");
    }

    public void sleep() {
        System.out.println("睡觉ing");
    }
}

// 利用继承使Student类 复用Person的类定义代码
class Student extends Person {

    int studentId;

    public Student() {
        // 先调用父类构造方法
        studentId = fatherI + 10;
    }

    public void study() {
        System.out.println("学习ing");
    }

}
/*
     子类对象的显示初始化

     如何调用调用父类的构造方法呢? 通过super关键字实现

    super关键字:  super代表父类对象的引用。
    this关键字:  表示当前对象的引用         super关键字:  super代表父类对象的引用。
    this访问 当前对象的成员变量值            super 访问父类对象中,成员变量的值
    this访问 当前对象的成员方法              super 访问父类对象,成员方法
    this 调用 当前类中定义的构造方法         super  调用父类中定义的构造方法
    this(实参列表)                          super(实参列表)

    所以,总结一下,通过super关键子super(实参列表),调用到父类定义的构造方法。

    如何实现子类对象的显示初始化?
        只需要在子类构造方法的第一条语句,先调用父类的构造方法,在执行子类构造方法的方法体即可
    注意事项:
    1. 必须保证,子类每个构造方法,都要满足子类对象的初始化流程
    2. 在子类构造方法中,通过super调用,父类构造方法时,该super语句,
       必须出现在,子类构造方法第一条语句的位置
    3. this()(调用当前类的构造方法) 和 super()(调用父类的构造方法)都可以,写在构造方法的方法体中, 它们都需要在第一条语句的位置
       它们不能共存
    4. 父类 成员变量初始化语句 构造代码块都,优先于子类中 成员变量的初始化语句,
       构造代码块执行

 */
public class Demo1 {

    public static void main(String[] args) {

        // 创建子类对象
        int sonI = 10;
        int fatherI = 100;
        ExplicitSon explicitSon = new ExplicitSon(sonI, fatherI);
//
//        System.out.println(explicitSon.fatherI);
//
//        System.out.println(explicitSon.sonI);
    }
}

class ExplicitFather {

    int fatherI;

    /*
          父类中定义的构造代码块
     */
    {
        System.out.println("father");
    }

//    public ExplicitFather() {
//        this.fatherI = 100;
//    }

    public ExplicitFather(int fatherI) {
        this.fatherI = fatherI;
    }
}

class ExplicitSon extends ExplicitFather {

    int sonI;

    /*
        子类中定义的构造代码块
     */
    {
        System.out.println("son");
    }

    public ExplicitSon (int sonI, int fatherI) {
        // 先调用父类有参构造方法,必须出现在子类第一条语句的位置
        super(fatherI);
        this.sonI = sonI;
    }

    public ExplicitSon() {
        super(10);
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值