Java笔记七(封装,继承与多态)

封装

该露的露,该藏的藏

程序设计追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用

封装(数据的隐藏)

通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问

属性私有

package com.oop.demo04;
//类 private:私有
public class Student {
    //属性私有
    private String name; //名字
    private int id;   //学号
    private char sex;    //性别
package com.oop.demo04;

public class Application {
    public static void main(String[] args) {
        Student s1=new Student();
        s1.name//错误代码
    }
}

此时如果直接调用s1.name则会报错,因为属性私有

正确方法:

package com.oop.demo04;
//类 private:私有
public class Student {
    //属性私有
    private String name; //名字
    private int id;   //学号
    private char sex;    //性别

    //提供一些可以操作这个属性的方法
    //提供一些public的get.set方法
    //get获得这个数据
    public  String getName(){
        return this.name;
    }
    //set给这个数据设置值
    public void setName(String name){
        this.name=name;
    }

}
package com.oop.demo04;

public class Application {
    public static void main(String[] args) {
        Student s1=new Student();
        s1.setName("佳伟");
        System.out.println(s1.getName());
    }
}

快捷键alt+ins快速生成get和set方法

Java笔记七(封装,继承与多态)_第1张图片

对用户的输入进行限制,以年龄为例:

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;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {//对输入不合法的年龄进行限制
        if (age>120||age<0){
            this.age=3;
        }else {
            this.age=age;
        }
    }

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


    }

}
package com.oop.demo04;

public class Application {
    public static void main(String[] args) {
        Student s1=new Student();
        s1.setName("佳伟");
        System.out.println(s1.getName());
        s1.setAge(999);
        System.out.println(s1.getAge());
    }
}

此时年龄便会输出不合法

封装的意义:

1.提高程序的安全性,保护数据

2.隐藏代码的实现细节

3.统一接口

4.系统可维护性

继承

继承的本质是对某一批类的抽象

extends的意思是“扩展”。子类是父类的扩展

JAVA中类只有单继承,没有多继承

继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。

假设Person是父类,Student与Teacher是子类

则可这样写

package com.oop.demo05;

public class Person {
}
package com.oop.demo05;

public class Student extends Person {
}
package com.oop.demo05;

public class Teacher extends Person {
}

子类继承父类,就会拥有父类的全部方法

package com.oop.demo05;

public class Person {
    public void say(){
        System.out.println("说了一句话");
    }
}
package com.oop.demo05;

public class Application {
    public static void main(String[] args) {
        Student student=new Student();
        student.say();
    }
}

但是拥有父类的所有方法不代表可以使用父类的所有方法,例如使用封装的关键词private

package com.oop.demo05;

public class Person {
    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;
        }
    }

则子类需使用父类设置的方法使用

package com.oop.demo05;

public class Application {
    public static void main(String[] args) {
        Student student=new Student();
        student.say();
        System.out.println(student.getMoney());
    }
}

IDEA快捷键:

ctrl+H:查看程序树

super

调用父类,如下

package com.oop.demo05;

public class Student extends Person {
    private String name="jiawei";
    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);//调用父类

    }
}
package com.oop.demo05;

public class Person {
    protected String name="weiwei";
    public void print(){
        System.out.println("Person");
    }
}
package com.oop.demo05;
import com.oop.demo05.Person;
import com.oop.demo05.Student;

public class Application {
    public static void main(String[] args) {
        Student student=new Student();
        student.test("佳伟");
    }
}

运行结果如下

调用父类方法:

package com.oop.demo05;

public class Person {
    protected String name="weiwei";
    public void print(){
        System.out.println("Person");
    }
}
package com.oop.demo05;

public class Student extends Person {
    private String name="jiawei";
    public void print(){
        System.out.println("Student");
    }
    public void test1(){
        print();//当前类
        this.print();//当前类
        super.print();//调用父类
    }
    public void test(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);//调用父类

    }

}
package com.oop.demo05;
import com.oop.demo05.Person;
import com.oop.demo05.Student;

public class Application {
    public static void main(String[] args) {
        Student student=new Student();
        //student.test("佳伟");
        student.test1();
    }
}

运行结果如下

Java笔记七(封装,继承与多态)_第2张图片

私有的东西同样无法被继承

注意调用父类的构造器必须放在子类构造器的第一行

super注意点

1.super调用父类的构造方法,必须在构造方法的第一个

2.super必须只能出现在子类的方 法或者构造方法中

3.super和this不能同时调用构造方法

与this对比

代表的对象不同

this:本身调用者这个对象

super:代表父类对象的应用

前提

this:没有继承也可以使用

super:只能在继承条件才可以使用

this():本类的构造

super():父类的构造

方法的重写

静态方法:

package com.oop.demo05;

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

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

import com.oop.demo05.A;
import com.oop.demo05.B;

public class Application {
    public static void main(String[] args) {
        //方法的调用只和左边,定义的数据类型有关
        A a=new A();
        a.test();
        //父类的引用指向了子类
        B b=new A();
        b.test();

    }
}

运行结果如下:

可以发现方法的调用只和左边,定义的数据类型有关

非静态方法的重写:

A与B同时去掉static

package com.oop.demo05;

public class B {
    public void test() {
        System.out.println("B=>test()");
    }
}
package com.oop.demo05;

public class A extends B{
    public void test() {
        System.out.println("A=>test()");
    }
}
package com.oop.demo05;

import com.oop.demo05.A;
import com.oop.demo05.B;

public class Application {
    public static void main(String[] args) {
        //方法的调用只和左边,定义的数据类型有关
        A a=new A();
        a.test();
        //父类的引用指向了子类
        B b=new A();//子类重写了父类的方法
        b.test();

    }
}

运行结果如下

alt+ins快捷键:快速重写方法

Java笔记七(封装,继承与多态)_第3张图片

静态的方法与非静态的方法区别很大

此时子类才重写了父类的方法,才算重写

重写的关键词只能是public

重写:需要有继承关系,子类重写父类的方法!

1.方法名必须相同

2.参数列表必须相同

3.修饰符:范围可以扩大:public>Protected>Default>private

4.抛出的异常:范围,可以被缩小,但不能扩大:ClassNotFoundException——>Exception(大)

重写,子类的方法和父类必要一致;方法体不同!

为什么需要重写:

父类的功能,子类不一定需要或者不一定满足

多态

package com.oop.demo06;

public class Application {
    public static void main(String[] args) {
        //一个对象的实际类型是确定的
        //new Student();
        //new Person();
        //可以指向的引用类型就不确定了
        //Student能调用的方法都是自己的或者继承父类的
        Student s1=new Student();
        //Person父类型,可以指向子类,但是不难调用子类独有的方法
        Person s2=new Student();//父类的引用指向子类
        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
        s2.run();//子类重写了父类的方法,执行子类的方法
        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");

    }
}

运行结果:

子类能调用的方法都是自己的或者继承父类的

父类型可以指向子类,但是不能调用子类独有的方法

可以强制类型转换把s2从父类转换成子类

((Student)s2).eat();

多态注意事项:

1.多态是方法的多态,属性没有多态

2.父类和子类有联系 否则有类型转换异常 ClassCastException

2.存在条件:继承关系,方法需要重写,父类引用指向子类对象

不能重写的关键词:

1.static 方法,属于类,它不属于实例

2.final 常量

2.private方法

你可能感兴趣的:(Java笔记,笔记,java)