Java 面向对象编程(第二篇)

Java 面向对象编程(第二篇)


1. 封装

通常,应禁止直接访问一个对象中的数组的实际表示,而应通过操作接口来访问,这称为信息的隐藏
属于私有,get/set

封装:

package com.oop.demo04;

// 类  private:私有
public class Student {

    //属性私有

    //名称
    private String name;

    //学号
    private int id;

    //性别
    private char sex;

    //年龄
    private int age;

    //提供一些可以操作这些属性的方法
    // 提供一些public 的get、set方法

    // get 获得这个属性
    public String getName(){
        return this.name;
    }

    // set 给这个数据设置值
    public void setName(String name){
        this.name = name;
    }

    // Alt+insert
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public char getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age>120 || age<0){
            this.age = 3;
        }else{
            this.age = age;
        }
    }
}
  1. 提高代码的安全性,保护数据
  2. 提高代码的实现细节
  3. 统一接口
  4. 系统的可维护性增加了

调用:

package com.oop.demo04;

public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();

        String name = s1.getName();
        System.out.println(name);
        s1.setName("zzk");
        System.out.println(s1.getName());

        s1.setAge(40); // 不合法
        System.out.println(s1.getAge());
    }
}

2. 继承

继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
extends的意思是“扩展”。子类是父类的扩展!
JAVA中类只有单继承,没有多继承!
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用extends来表示
子类和父类之间,从意义上讲应该具有“is a”的关系。
object类
super
方法重写

2.1 object类
package com.oop.demo05;

// 在Java中,所有的类,都直接或者间接继承Object类
// 人
public class Person /*extends Object*/{

    // public 公共的
    // protected 保护
    // default 默认
    // private 私有的
    private int money = 10_0000_0000;
    public void say(){
        System.out.println("说了一句话");
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}
2.2 super

super注意点

1.super是调用父类的构造方法,必须在构造方法的第一个。
2.super必须只能吃现在子类的方法或者构造方法中!
3.super 和 this 不能同时调用构造方法!

super vs this

代表的对象不同:
1.this:本身调用者这个对象
2.super:代表父类对象的应用
前提:
this:在没有继承的情况下也可以使用。
super:只能在继承条件下才可以使用。
构造方法
this();本类的构造
super();父类的构造

package com.oop.demo05;

// 学生
public class Student extends Person{
    private String name = "mango";

    public Student() {
        // 隐藏代码:调用了父类的无参构造
        // 调用父类的构造器 必须要在子类构造器的第一行
        // 父类如果没有无参构造,子类就无法使用无参构造
        super();
        //this() 只能调用一个
        System.out.println("Student无参执行了");
    }

    public Student(String name) {
        this.name = name;
    }

    public void print(){
        System.out.println("Student");
    }
    public void test(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    }
    public void test1(){
        print();
        this.print();
        super.print();

    }

}
2.3 方法的重写

重写都方法的重写,和属性无关

2.3.1 静态方法(static)

A:

package com.oop.demo05;

public class A extends B{
    
    public static void test() {
        System.out.println("A=>test()");
    }
}

B:

package com.oop.demo05;

// 重写都方法的重写,和属性无关
public class B {

    public static void test() {
        System.out.println("B=>test");
    }
}

输出结果:
A=>test() B=>test

2.3.2 非静态方法

A:

package com.oop.demo05;

public class A extends B{

    @Override
    public void test() {
        System.out.println("A=>test()");
    }
}

B:

package com.oop.demo05;

// 重写都方法的重写,和属性无关
public class B {

    public void test() {
        System.out.println("B=>test");
    }
}

输出结果:
A=>test() A=>test

区别:

静态方法调用只和左边,定义的数据类型有关
非静态方法重写了父类的方法

非静态的才是重写!!!(重写的关键字是public)

重写总结:

  1. 需要有继承关系,子类重写父类的方法!
  2. 方法名必须相同。
  3. 参数列表必须相同。
  4. 修饰符:可以被扩大,但是不可以缩小。public>protected>default>private
  5. 抛出异常:范围,可以被缩小,但不能扩大:ClassNotFoundException --> Exception
  6. 重写,子类的方法和父类必要一致:方法体不同!

为什么需要重写?

  1. 父类的功能,子类不一定需要,或者不一定满足!
  2. Alt + Insert : override; 重写

3.多态

  • 动态编译:动态编辑
  • 即同一种方法可以根据发送对象的不同而采用多种不同的行为方式。
  • 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。

多态存在的条件:

  1. 有继承关系
  2. 子类重写父类方法
  3. 父类引用指向子类对象

注意:多台是方法的多态,属性没有多态性。instanceof

主程序:

package com.oop.demo06;

public class Application {

    public static void main(String[] args) {
        // 一个对象的实际类型是确定的



        // 可以指向的引用类型就不确定:父类的引用指向子类

        // Student 能调用的方法都是自己的 或者都是继承父类的
        Student s1 = new Student();
        // Person 父类型,可以指向子类,但是不能调用子类独有的方法。
        Person s2 = new Student();
        Object student = new Student();


        s2.run(); // 子类重写了父类的方法
        s1.run();

        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!

        ((Student) s2).eat(); // 子类重写了父类的方法,执行子类的方法
        s1.eat();
    }

}

子类:

package com.oop.demo06;

public class Student extends Person{
    @Override
    public void run() {
        System.out.println("son");
    }

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

父类:

package com.oop.demo06;

public class Person {
    public void run(){
        System.out.println("run");
    }
}

注意事项:

  1. 多态是方法的多态,属性没有多态。
  2. 父类和子类,有联系 类型转换异常! ClassCastException!
  3. 存在的条件:继承关系、方法需要重写,父类的引用指向子类对象!Father f1 = new Son();

无法重写(无法多态):
1.static 方法,属于类,它不属于实例
2.final 常量
3.private 方法

4. instanceof 关键字

System.out.println(X instanceof Y);//能不能编译通过! X和Y有没有父子关系!

package com.oop.demo06;

public class Application {

    public static void main(String[] args) {

        // Object -> Person -> Student
        Object o = new Student();

        //        System.out.println(X instanceof Y);//能不能编译通过! X和Y有没有父子关系!

        System.out.println(o instanceof Student);
        System.out.println(o instanceof Person);
        System.out.println(o instanceof Object);
        System.out.println(o instanceof Teacher);
        System.out.println(o instanceof String);
        System.out.println("===============");

        /*
        *
        *   true
            true
            true
            false
            false
        */

        //  Person -> Student
        Person p = new Student();
        System.out.println(p instanceof Student); // true
        System.out.println(p instanceof Person); // true
        System.out.println(p instanceof Object); // true
        System.out.println(p instanceof Teacher); // false
        //System.out.println(p instanceof String); // 编译就报错
        System.out.println("===============");

        Student s = new Student();
        System.out.println(s instanceof Student); // true
        System.out.println(s instanceof Person); // true
        System.out.println(s instanceof Object); // true
        //System.out.println(s instanceof Teacher); // 编译就报错
        //System.out.println(p instanceof String); // 编译就报错
    }

}

5. 类型转换

父转子:

package com.oop.demo06;

public class Application {

    public static void main(String[] args) {
        // 类型之间的转换:基本类型转换 高低

        // 类型之间转换: 父类 子类

        // 高                低
        Person student = new Student();

        // student将这个对象转换为Student类型,我们就可以使用Student类型的方法了!

        ((Student)student).go();
    }

}

子转父:
子类转换为父类,可能会丢失自己本来的一些方法!

package com.oop.demo06;

public class Application {

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

        Person person = student;
    }

}

小结:

  1. 父类引用指向子类的对象。
  2. 把子类转换为父类,向上转型;可能用不了子类的方法
  3. 把父类转换为子类,向下转型;(强制转换)
  4. 方便方法的调用,减少重复的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值