java入门12--面向对象(上)

Posted acrifhy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java入门12--面向对象(上)相关的知识,希望对你有一定的参考价值。

java入门12

面向过程与面向对象

  • 面向过程思想

    • 步骤清晰,线性思维
    • 适合处理简单问题
  • 面向对象思想

    • 分类思维,对不同类的任务单独思考

    • 适合复杂问题,多人合作

什么是面向对象

  • 面向对象编程(Object-Oriented Programming,OOP)

  • 面向对象编程本质:以类的方式组织代码,以对象的组织封装数据

  • 抽象

  • 三大特性

    • 封装
    • 继承
    • 多态
  • 从代码角度,先有类后有对象,类是对象的模板

类与对象的关系

  • 类是对某一类事物的定义,是抽象的数据类型,对象是抽象概念的具体实例

创建与初始化对象

  • 使用new关键字创建对象
  • 使用new时,除了分配内存空间,还会为创建的对象进行默认初始化以及对类中构造器的调用
  • 类中的构造器也叫构造方法,是创建对象时必须调用的,构造器特点:
    • 必须和类名相同
    • 必须没有返回类型,也不能写void

比如创建一个学生类:

package oop;

//学生类
public class Student 
    //属性
    String name;
    int age;

    //方法
    public void study()
        System.out.println(this.name+"在学习");
    

实例化对象:

package oop;

public class Demo01 
    public static void main(String[] args) 
        //实例化
        //类实例化后会返回一个自己的对象
        //student对象就是一个Student类的具体实例

        Student srrdhy1 = new Student();
        Student srrdhy2 = new Student();

        srrdhy1.name = "艾伦耶格尔";
        srrdhy1.age = 19;

        System.out.println(srrdhy1.name);
        System.out.println(srrdhy1.age);
        srrdhy1.study();
        //艾伦耶格尔
        //19
        //艾伦耶格尔在学习
    

有参构造与无参构造

类:

package oop;

public class Hero 

    //一个类即使什么也不写,也有一个方法
    //显示的定义构造器

    String name;

    //实例化初始值
    //使用new关键字,本质在调用构造器
    //用来初始化值
    public Hero()
        this.name = "奥克斯";
    
    //有参构造:一旦定义了有参构造,无参必须显示定义
    public Hero(String name)
        this.name = name;
    

主函数执行:

package oop;

public class Demo01 
    public static void main(String[] args) 

        //实例化一个对象
        Hero hero1 = new Hero();
        Hero hero2 = new Hero("黑魔");

        System.out.println(hero1.name);
        System.out.println(hero2.name);
        //奥克斯
        //黑魔
    

//alt + insert用于生成构造器
public Hero(String name) 
        this.name = name;
    

    public Hero() 
    

选择Constructor,直接OK生成有参构造,选择Select None生成无参构造。

封装

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

  • 封装(数据的隐藏)

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

创建一个类:

package oop.demo02;

//学生类  private:私有  不能直接在main方法调用了
//这时我们使用public的get和set方法来操作
public class Student 
    //名字
    private String name;
    //学号
    private int id;
    //性别
    private char sex;
    //get获得这个数据
    public String getName()
        return this.name;
    
    //set给这个数据设置值
    public void setName(String name)
        this.name = name;
    

主函数:

public class Main 
    public static void main(String[] args) 
        Student s1 = new Student();
        s1.setName("srrdhy");
        String name1 = s1.getName();
        System.out.println(name1);//srrdhy
    

快捷操作:

    //alt + insert选择Getter and Setter
    //自动生成
    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) 
        this.age = age;
    

设置一个999岁,但999年龄是不合理的:

s1.setAge(999);
System.out.println(s1.getAge());//非法年龄

规避操作:

    public void setAge(int age) 
        if (age<120 && age>0)
            this.age = age;
        else 
            System.out.println("输入非法");
        
    

封装好处:

  • 提高程序安全性,保护数据
  • 隐藏代码实现细节
  • 统一接口get、set
  • 系统可维护性提高

继承

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
  • extends意为扩展,子类是父类的扩展
  • java类只有单继承(一个子类不能有多个父类)
  • 除了继承,类与类间的关系还有依赖、组合、聚合
  • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
  • 子类与父类间从意义上具有"is a"的关系
  • object类
  • super
  • 方法重写

我们建立一个父类并赋予一个方法:

//人类 父类
public class Person 
    public void speak()
        System.out.println("说了些什么");
    

建立一个子类继承父类,什么方法也没有写:

//学生 子类
public class Student extends Person

这时在主程序中new一个Student对象,使用speak():

public class Main 
    public static void main(String[] args) 
        Student student1 = new Student();
        student1.speak();
    

可以输出,这表示子类可以调用父类的方法

再比如我们在父类中增加

public int money = 10_0000_0000;

调用:

System.out.println(student1.money);

也可以输出,子类会继承父类的一切

但如果我们把父类的money改为私有的:

private int money = 10_0000_0000;

子类就调用不了了

对于调用权限,由高到低为:

public
protected
default
private

使用快捷键ctrl+H会生成树结构(要把鼠标点在需要的类里)

可以发现,父类上还有一个类,因为在java中,所有的类默认继承Object类

现在我们在父类建立一个名字,采用protected。

public class Person 

    protected String name = "srrdhy";

子类中用private建立一个不同的名字,再写一个输出名字的方法,分别输出三种名字:

public class Student extends Person

    private String name = "琪亚娜";
    public void printname(String name)
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    

主程序运行:

public class Main 
    public static void main(String[] args) 
        Student student1 = new Student();
        student1.printname("雷电芽衣");
    
    //雷电芽衣
    //琪亚娜
    //srrdhy

如果我们在父类中写一个print方法:

public void print()
        System.out.println("Person");
    

又在子类中写一个同名方法:

public void print()
        System.out.println("Student");
    

那么主程序调用print方法时,会调用子类的print

注意,private无法继承,super也不行

现在我们在子类父类各写一个无参构造:

public Student() 
        System.out.println("Student无参执行");
    
public Person() 
        System.out.println("Person无参执行");
    

主程序中单纯new一个student,什么也不做,会输出:

Person无参执行
Student无参执行

先输出了Person无参执行,说明public Student()里隐藏调用了父类的无参构造,隐藏了一个super()

调用父类的构造器,必须要在子类的第一行

父类没有无参时,子类也不能写无参,只能调用有参。一般我们会把无参写上再接着写有参。

方法重写

  1. 重写都是方法的重写,与属性无关

  2. 子类重写父类的同名方法,参数列表相同

  3. 修饰符:范围可以扩大不能缩小:public>protected>default>private,当然private不能重写

  4. 抛出异常:范围可以缩小不能扩大:ClassNotFoundException–>Exception(大)

子类方法与父类一致,方法体不同

为什么要重写:

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

我们建一个子类A,父类B,并写同名方法:

public class A extends B
    public static void text()
        System.out.println("A");
    

public class B 
    public static void text()
        System.out.println("B");
    

调用方法:

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

删去A、B的static,发现左边都多了一个东西:

其实就代表重载

删掉A中方法,alt+insert选择方法重载,直接回车生成方法:

@Override//注解,有功能的注释
    public void text() 
        super.text();
    

继续执行主程序,输出BB,把super.text();改回System.out.println(“A”);,继续执行主程序,输出却变成了AA

所以我们可以补全刚刚的结论:

  • 静态方法(有static):方法的调用只和左边,定义的数据类型有关
  • 非静态方法:重写(比如B b = new A();b.text();)

注意重写的方法只能是public,换成private就不行了

以上是关于java入门12--面向对象(上)的主要内容,如果未能解决你的问题,请参考以下文章

学号20182335 2019-2020-1 《数据结构与面向对象程序设计》实验四报告

# 学号 2019-2020-1 《数据结构与面向对象程序设计》第1周学习总结

20165306 实验二 Java面向对象程序设计

Java从入门到天黑|05JavaSE入门之面向对象(上)

Java从入门到天黑|05JavaSE入门之面向对象(上)

2018-2019-2 20175211 实验二《Java面向对象程序设计》实验报告