Java面向对象编程2:面向对象的三大特征(重点)

本文详细介绍了Java面向对象的三大特性:封装、继承和多态。封装强调信息隐藏,通过get/set方法访问属性;继承允许子类拓展父类功能,Java中单继承;多态则表现为子类对象可以被视为父类对象,实现不同行为。文中还涉及到super关键字的使用和方法重写的原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java面向对象编程

Java的核心就是OOP(面向对象)

4、面向对象的三大特性(重点)

封装

  1. 该露的露,该藏的藏:

    • 我们程序设定要追求高内聚,多耦合
    • 高内聚:累的内部数据操作细节自己完成,不允许外部干涉;
    • 多耦合:仅暴露少量的方法给外部使用。
  2. 封装(数据的隐藏)

    • 通常应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
  3. 记住一句话:属性私有,get/set

  4. 下面进行简单的操作:

    package com.oop.demo04;
    
    public class Student {
    
        /*
        封装:
          1.提高程序的安全性,保护数据
          2.隐藏代码的实现细节
          3.统一接口
          4.增加系统可维护性
         */
        //private属性私有,不能直接被使用
        private String name;//名字
        private int age;//学号
        private char sex;//性别
    
        //提供一些可以操作这个属性的方法!
        //提供一些public 的get、set方法
    
        //get 获得这个数据
        public String getName(){
            return this.name;
        }
    
    
        //set 给这个数据设置值
        public void setName(String name){
            this.name = name;
        }
    
        public int getAge(){
            return this.age;
        }
    
        //给年龄设置一个范围
        public void setAge(int num){
            if (age>150||age<0){
                this.age = 3;
            }else {
                this.age = num;
            }
        }
    
        public char getSex(){
            return this.sex;
        }
    
        public void setSex(char sex){
            this.sex = sex;
        }
    }
    
    public class Application {
        public static void main(String[] args) {
            Student s1 = new Student();
            s1.setName("小明");
            System.out.println(s1.getName());
    
            s1.setNum(999);
            System.out.println(s1.getNum());
        }
    }
    

继承

  1. 继承的本质是对某一批类的抽象,从而实现对世界更好的建模。

  2. extends的意思是"拓展"。子类是父类的拓展。

  3. JAVA中类只有单继承,没有多继承!

  4. 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。

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

  6. 子类(派生类)和父类(基类)之间,从意义上讲应该具有**“子类 is 父类”**的关系。

  7. 下面进行特殊的操作:

    • 设置一个父类(基类)Father、两个子类Son和Dau
    • 父亲拥有10个亿(私有的private)
    • 这时候子类不能直接使用父类的10个亿
    • 这时候需要get/set
    package com.oop.demo05;
    //在JAVA中,所有的类都默认直接或者间接继承object
    //Father:父类/基类
    public class Father/*extends object*/ {
        //private私有的,不能直接被使用,必须get/set
        private int money = 10_0000_0000;
    
        //获取这个数据
        public int getMoney(){
            return money;
        }
    
        //给这个数据设置值
        public void setMoney(int money){
            this.money = money;
        }
    }
    
    • 然后子类通过extends继承父类
    package com.oop.demo05;
    //son:派生类/子类
    //子类继承了父类,就会拥有父亲的全部方法!
    //son is father
    public class Son extends Father {}
    
    • 然后可以直接通过子类调用父类的方法
    public class Application {
        public static void main(String[] args) {
            //使用new关键字,调用构造器
            Son son = new Son();
            son.getMoney();//获得这个数据
            son.setMoney(5000);//设置这个数据
            System.out.println(son.getMoney());//输出5000
        }
    }
    
    • 一般情况下父类要给子类调用方法会用public

在这里插入图片描述

拓展
object类
  1. object类:在JAVA中,所有的类都默认直接或者间接继承object
super 详解

下面先进行几个简单的操作:

  1. 操作一:super 出现在子类的方法(有参)
  • 父类
package com.oop.demo06;

public class Father {
    protected String name = "songge";
}
  • 子类
package com.oop.demo06;

public class Son extends Father {
    String name = "tongxin";
    public void say(String name){
        //传递参数name;
        System.out.println(name);
        //直接调用这个类的name;
        System.out.println(this.name);//tongxin
        //super调用了父类的name;
        System.out.println(super.name);//songge
    }
}
  • 输出
public class Application {
    public static void main(String[] args) {

        Son son = new Son();
        son.say("松哥");
    }
}
  • 运行后显示

在这里插入图片描述

  1. 操作二:super 出现在子类的方法(无参)
  • 父类
package com.oop.demo06;

public class Father {
    public void test(){
        System.out.println("tongxin");
    }
}
  • 子类
package com.oop.demo06;

public class Son extends Father {
    
    public void test(){
        System.out.println("songge");
    }
    public void say1(){
        test();//调用这个类的test;
        this.test();//调用这个类的test;
        super.test();//调用父类的test;
    }
}
  • 输出
public class Application {
    public static void main(String[] args) {

        Son son = new Son();
        son.say1();
    }
}
  • 运行后显示

在这里插入图片描述

  1. 操作二:super 调用父类的构造方法(无参)
  • 父类
package com.oop.demo06;


public class Father {
    //父类的无参构造
    public Father() {
        System.out.println("Father无参构造");
    }
}
  • 子类
package com.oop.demo06;

public class Son extends Father {

    public Son() {
        //运行后先输出了父类的无参构造,然后输出了子类的无参构造
        //说明这里隐藏了代码:super();默认调用了父类的无参构造
        System.out.println("Son无参构造");
    }
}
  • 输出
public class Application {
    public static void main(String[] args) {

        Son son = new Son();
    }
}
  • 运行后显示

在这里插入图片描述

super总结 :

super注意点:
     1.super 调用父类的构造方法,必须在构造方法的第一个
     2.super 只能出现在子类的方法或者构造方法中!
     3.superthis 不能同时调用构造方法!
     
superthis对比:
     1.代表的对象不同
      - this : 本身调用者这个对象
      - super: 代表父类对象的应用
     2.前提:
      - this : 没有继承也能使用
      - super: 只能在继承条件下使用
     3.
      - this() : 本类的构造
      - super(): 父类的构造
方法重写

下面先进行几个简单的操作:

  1. 操作一:当调用方法是静态方法的时候,不存在重写
  • 父类
package com.oop.demo07;

public class A {

    public static void test() {
        System.out.println("A is num1");
    }
}
  • 子类
package com.oop.demo07;
//继承关系
//静态方法的时候
public class B extends A{
    public static void test(){
        System.out.println("B is num1");
    }
}
  • 输出
package com.oop.demo07;

public class Application {
    public static void main(String[] args) {
        //当静态方法的时候,不存在重写
        //方法的调用只和左边定义的数据类型有关
        A a = new B();
        a.test();//输出A
        //父类的引用指向了子类
        B b = new B();
        b.test();//输出B
    }
}
  • 运行后显示

在这里插入图片描述

  1. 操作二:当调用方法是非静态方法的时候,才会存在重写

    • 父类
    package com.oop.demo07;
    //重写都是方法的重写,和属性无关
    public class A {
        public void test(){
            System.out.println("A--a");
        }
    }
    
    • 子类
    package com.oop.demo07;
    //继承关系
    public class B extends A{
        //快捷键Alt+Insert --> Override
        //Override 重写
        @Override//注解:有功能的注释!
        public void test() {
            System.out.println("B--b");
        }
    }
    
    • 输出
    public class Application {
        public static void main(String[] args) {
            //当非静态方法的时候,才有重写
            //子类重写了父类的方法
            A a = new B();
            a.test();//输出B
            B b = new B();
            b.test();//输出B
        }
    }
    
    • 运行后显示

在这里插入图片描述

重写总结

重写:需要有继承关系,子类重写父类的方法!
   1.方法名必须相同
   2.参数列表必须相同
   3.修饰符:范围可以扩大:
   Public>Protectded>Default>Private
   4.抛出的异常:范围可以被缩小,但不能被扩大
   classNotFoundException-->FoundException(范围特别大)

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

重写的意义:
   1.父类的功能子类不一定需要/满足
   2.快捷键Alt+Insert--->Override

多态

  1. 即同一个方法可以根据发送对象的不同而采取多种不同的行为方式。

  2. 一个对象的实际类型是确定的,但可以指向对象的引用的类型(父类/有关系的类)有很多。

  3. 多态注意事项:

    • 多态是方法的多态,属性没有多态性。
    • 必须是有联系的类,父类与子类之间
    • 如果是没有关系的两个类,会出现类型转换异常!:ClassCastException!
    • 多态存在的条件:
      • 有继承关系
      • 子类重写父类方法
      • 父类引用指向子类对象!
    • 有些方法不能被重写:
      • 静态方法,含static的方法,他属于类,不属于实例;
      • final 常量;
      • 属性私有的方法,含private的方法
  4. 下面先进行简单的操作:

    • 父类
    package com.oop.demo08;
    
    public class Person {
        public void say(){
            System.out.println("我是谁!");
        }
    
    }
    
    • 子类
    package com.oop.demo08;
    
    public class Student extends Person{
        //重写父类的方法
        public void say(){
            System.out.println("谁是我");
        }
        //子类独有的方法
        public void eat(){
            System.out.println("美味!");
        }
    }
    
    • 输出
    import com.oop.demo08.Student;
    import com.oop.demo08.Person;
    public class Application {
        public static void main(String[] args) {
            /*
            一个对象的实际类型是确定的
            例如 Student student = new Student();
                 Person person = new Person();
             */
    
            //可以指向的引用类型就不确定了:父类引用指向子类
            //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
            //Student能调用的方法都是自己的或者继承父类的!
            Student s1 = new Student();
            //Person 父类型,可以指向子类,但是不能调用子类独有的方法
            Person s2 = new Student();
            Object s3 = new Student();
    
            //子类执行自己的方法
            s1.say();//输出 谁是我
            //子类重写了父类的方法,执行子类的方法
            s2.say();//输出 谁是我
    
            //子类执行自己的方法
            s1.eat();//输出 美味!
            //父类想要执行子类独有的方法,把父类强行转换为子类,高转低
            ((Student)s2).eat();//输出 美味!
        }
    }
    
  5. instanceof (类型转换) 引用类型

    • 主要公式:System.out.println(A instanceof B);
    • 看代码能否编译通过
    • 取决于是否存在父子关系
    • 下面进行简单操作:
    public class Application {
        public static void main(String[] args) {
            //Object>String
            //Object>Person>Student
            //Object>Person>Teacher
    
            //看代码能不能编译通过!
            //取决于是否存在父子关系
            //System.out.println(A instanceof B);
    
            Object object = new Student();
            System.out.println(object instanceof Object);//true
            System.out.println(object instanceof Person);//true
            System.out.println(object instanceof Student);//true
            System.out.println(object instanceof Teacher);//false
            System.out.println(object instanceof String);//false
            System.out.println("=========================");
            Person person = new Student();
            System.out.println(person instanceof Object);//true
            System.out.println(person instanceof Person);//true
            System.out.println(person instanceof Student);//true
            System.out.println(person instanceof Teacher);//false
            //System.out.println(person instanceof String);//编译报错!
            System.out.println("=========================");
            Student student = new Student();
            System.out.println(student instanceof Object);//true
            System.out.println(student instanceof Person);//true
            System.out.println(student instanceof Student);//true
            //System.out.println(student instanceof Teacher);//编译报错!
            //System.out.println(student instanceof String);//编译报错!
        }
    }
    
  6. 类型转换

    • 父类引用指向子类的对象
    • 把子类转换为父类自动转换:低转高,可能会丢失一些方法
    • 把父类转换为子类强制转换:高转低,
    • 类型转换为了方便方法的调用,减少重复的代码!
    • 下面进行简单的操作
    package com.oop.demo09;
    
    public class Application {
        public static void main(String[] args) {
            //父类person引用指向Student,但是不能用子类独有的方法
            Person person = new Student();
    
            //这时候要先将person类强制转换为Student类
            //转换好的person1可以直接使用子类独有的方法
            Student person1 = (Student) person;
            person1.say();
    
            //一般直接将person强制转换为Student类型
            //这样可以直接使用子类独有的方法
            ((Student)person).say();
        }
    }
    

Static关键字详解

  1. 被static修饰的方法或变量随着类加载的时候就加载了,可以不用new对象,直接调用

    • 静态的变量
    package com.oop.demo10;
    //static
    public class Student {
        //静态变量 static
        //随着类加载的时候就加载了,可以不用new对象,直接调用
        private static int age;
        private double score;//非静态的变量
    
        public static void main(String[] args) {
            Student s1 = new Student();
            System.out.println(Student.age);
            //System.out.println(Student.score);//不能直接调用
            System.out.println(s1.age);
            System.out.println(s1.score);
        }
    }
    
    • 静态的方法
    package com.oop.demo10;
    
    public class Teacher {
        //非静态方法
        public void say(){
            go();//非静态方法可以直接调用静态方法
            System.out.println("来");
        }
        //静态方法 static
        //随着类加载的时候就加载了,可以不用new对象,直接调用
        public static void go(){
            System.out.println("走");
        }
    
        public static void main(String[] args) {
            go();//直接调用
            new Teacher().say();//不能直接调用
        }
    }
    
  2. 静态代码块

    • 可以加载一些初始化的东西
    • 静态代码块跟类加载的时候一起执行
    • 最开始执行并只执行一次
    package com.oop.demo10;
    
    public class Person {
    
        /*
        2.匿名代码块:
        - 附初始值
        - 跟对象同时产生,在构造方法之前
         */
        {
            System.out.println("匿名代码块");
        }
        /*
        1.静态代码块:
        - 可以加载一些初始化的东西
        - 静态代码块跟类加载的时候一起执行
        - 最开始执行并只执行一次
         */
        static {
            System.out.println("静态代码块");
        }
        //3.构造方法
        public Person(){
            System.out.println("构造方法");
        }
    
        public static void main(String[] args) {
            Person person = new Person();
            System.out.println("=========");
            Person person1 = new Person();
        }
    }
    
    • 运行后显示:

    在这里插入图片描述

  3. 静态的导入包

    • 没有导入random的时候必须输入Math.random
    public class Application {
        public static void main(String[] args) {
            System.out.println(Math.random());
        }
    }
    
    • 但是不能直接导入到random,可以加个static变成静态导入包,这样可以直接使用random
    //静态导入包
    import static java.lang.Math.random;
    import static java.lang.Math.PI;
    
    public class Application {
        public static void main(String[] args) {
            System.out.println(random());
            System.out.println(PI);
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dominator945

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值