java6:面向对象编程

面向对象编程

(一)初步认识

面向过程 & 面向对象

  • 面向过程:
    • 步骤清晰简单,第一步做什么,第二步做什么
    • 面向过程适合处理一些较为简单的问题
  • 面向对象:
    • 简单来说就是将一个问题分割成多个过程
    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题

什么是面向对象

  • 面向对象编程(Object-Oriented Programming,OOP)
  • 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据
  • 三大特性:
    • 封装
    • 继承
    • 多态
  • 从认识论角度考虑是 先有对象后有类。对象,是具体的事物;类,是抽象的,是对对象的抽象
  • 从代码运行的角度考虑是 现有类后有对象。类是对象的模板

(二)方法

  • 静态方法(static)

    • 在方法中添加static,在主函数中可以直接调用

    在这里插入图片描述

    public class OOP1 {
        public static void main(String[] args) {
            OOP2.showHello();
        }
    }
    
    public class OOP2 {
        public static void showHello(){
            System.out.println("Hello!");
        }
    }
    
  • 非静态方法

    • 需要实例化类(new)才能调用

    在这里插入图片描述

    public class OOP1 {
        public static void main(String[] args) {
            // 第一种调用方式
            new OOP2().showHello();
    
            // 第二种调用方式
            // 实例化这个类(new)
            // 对象类型 对象名 = 对象值
            OOP2 oop2 = new OOP2();
            oop2.showHello();
        }
    }
    
    public class OOP2 {
        public void showHello(){
            System.out.println("Hello!");
        }
    }
    
  • 静态方法是和类一起加载的

  • 非静态方法是类实例化之后才存在的

    • 静态方法间的调用
    public class OOP1 {
        public static void main(String[] args) {
            a();
            System.out.println("=====");
            b();
        }
    
        // 两个方法都是静态方法,可以互相调用
        public static void a(){
            b();
            System.out.println("a");
        }
    
        public static void b(){
            System.out.println("b");
        }
    }
    
    b
    a
    =====
    b
    
    • 非静态方法间的调用
    public class OOP1 {
        public static void main(String[] args) {
            OOP1 oop1 = new OOP1();
            oop1.a();
            System.out.println("=====");
            oop1.b();
        }
    
        public void a(){
            b();
            System.out.println("a");
        }
    
        public void b(){
            System.out.println("b");
        }
    }
    
    b
    a
    =====
    b
    
  • 错误调用

    public class OOP1 {
        public static void main(String[] args) {
            OOP1 oop1 = new OOP1();
            a();
            System.out.println("=====");
            oop1.b();
        }
    
        // 静态方法 和 非静态方法 生命周期不同,无法相互调用
        public static void a(){
            b();
            System.out.println("a");
        }
    
        public void b(){
            System.out.println("b");
        }
    }
    

    在这里插入图片描述

  • 值的传递

    • 两个a并不是同一个参数
    public class OOP1 {
        public static void main(String[] args) {
            int a = 1;
            System.out.println(a);
            System.out.println("=====");
            change(a);
            System.out.println(a);
        }
    
        public static int change(int a){
            a = 10;
            return a;
        }
    
    }
    
    1
    =====
    1
    
  • 引用传递:对象,本质还是值的传递

    public class OOP1 {
        public static void main(String[] args) {
            Person person = new Person();
            System.out.println(person.name);
            change(person);
            System.out.println(person.name);
        }
    
        public static void change(Person person){
            person.name = "Joy Won";
        }
    
    }
    
    class Person{
        String name;
    }
    
    null
    Joy Won
    

(三)对象的创建分析

  • 类与对象的创建
package com.joywon.oop2;

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

        student1.name = "JoyWon";
        student1.age = 10;
        student1.study();

        student2.name = "小明";
        student2.age = 5;
        student2.study();
    }
}
package com.joywon.oop2;

public class Student {
    String name;
    int age;

    public void study(){
        System.out.println(this.name + this.age + "岁,在学习!");
    }
}
JoyWon10岁,在学习!
小明5岁,在学习!

在这里插入图片描述

  • 构造器:无参构造器,分为有参构造器

    • 主要作用:1、new本质在调用构造方法;2、初始化值

    • 和类名相同

    • 没有返回值

    • 一个类即使什么都不写,它也会存在一个方法

在这里插入图片描述

  • 无参构造:

    package com.joywon.oop2;
    
    public class Application {
        public static void main(String[] args) {
            Student student = new Student();//new对象时,会进入public Student(){} 这个方法
            								//相当于python中的进入 def __init__() 这个方法
            System.out.println(student.name);
        }
    }
    
    package com.joywon.oop2;
    
    public class Student {
        String name;
        int age;
    
        public Student(){
            this.name = "JoyWon";
            this.age = 10;
        }
    }
    
    JoyWon
    
  • 有参构造:

    package com.joywon.oop2;
    
    public class Application {
        public static void main(String[] args) {
            //new对象时,会自动跳转到public Student(String name, int age){}
            Student student = new Student("JoyWon2", 11);
            System.out.println(student.name);
            System.out.println(student.age);
        }
    }
    
    package com.joywon.oop2;
    
    public class Student {
        String name;
        int age;
    
        public Student(){
            this.name = "JoyWon";
            this.age = 10;
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    JoyWon2
    11
    
  • 快捷键创建构造:alt+insert --> constructor --> 指定参数/无参数创建构造器

    在这里插入图片描述

    在这里插入图片描述

(四)面向对象三大特性

1、封装

  • 该露的露,该藏的藏
    • 我们程序设计要追求 “高内聚,低耦合”
    • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉
    • 低耦合:仅暴露少量的方法给外部使用
  • 封装(数据的隐藏)
    • 通常,应禁止访问一个 对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏
  • 属性私有(private),get/set
package com.joywon.oop2;

/*
*   1、提高代码的安全性,保护数据
*   2、隐藏代码的实现细节
*   3、同一接口
*   4、增加系统可维护性
* */
public class Application {
    public static void main(String[] args) {
        Pet dog = new Pet();
        dog.setName("旺财");
        dog.setAge(3);
        System.out.println(dog.getName() + dog.getAge() + "岁");
    }
}
package com.joywon.oop2;

public class Pet {
    //属性私有 
    private String name;
    private int age;

    //提供一些可以操作这个属性的方法
    //提供一些public的get、set方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
    // 可通过 alt+insert 快速生成get/set
}
旺财3

2、继承

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


public class Application {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.setName("旺财");
        dog.setAge(3);
        System.out.println(dog.getName() + dog.getAge() + "岁");
    }
}
package com.joywon.oop2;

public class Dog extends Pet{
    //ctrl+H 查看继承树
}

在这里插入图片描述

package com.joywon.oop2;

public class Pet {
    //属性私有
    private String name;
    private int age;

    //提供一些可以操作这个属性的方法
    //提供一些public的get、set方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    // 可通过 alt+insert 快速生成get/set
}
旺财3
  • Dog继承Pet中的全部方法:
    • 小细节:红色方框下的方法我们并没有写,为什么会存在呢?----在java中,所有的类,都默认直接或间接继承Object
    • public class Pet { } 等效于 public class Pet extends Object { }

在这里插入图片描述

2.2、super
  • 例1
package com.joywon.oop2;


public class Application {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.showName("旺财3");
    }
}
package com.joywon.oop2;

public class Pet {
    // 受保护的参数
    protected String name = "旺财1";
}
package com.joywon.oop2;

public class Dog extends Pet{
    // 私有的参数
    private String name = "旺财2";

    public void showName(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    }
}
旺财3
旺财2
旺财1

在这里插入图片描述

  • 例2:
package com.joywon.oop2;


public class Application {
    public static void main(String[] args) {
        Dog dog = new Dog();
    }
}
package com.joywon.oop2;

public class Dog extends Pet{
    // 隐藏代码:调用父类的无参构造
    public Dog() {
        // 这里隐藏了一句代码,super()必须放在第一行
        // 以为Dog继承了Pet,所以要先执行Pet的无参构造
        super();
        System.out.println("Dog无参执行了");
    }
}
package com.joywon.oop2;

public class Pet {
    public Pet() {
        System.out.println("Pet无参执行了");
    }
}
Pet无参执行了
Dog无参执行了

在这里插入图片描述

  • super注意点:
    • super调用父类的构造方法,必须在构造方法的第一行
    • super必须只能出现在子类的方法或者构造方法中
    • super和this不能同时调用构造方法
  • vs this:
    • 代表的对象不同:
      • this:本身调用者这个对象
      • super:代表父类对象的引用
    • 前提:
      • this:没有继承叶可以使用
      • super:只能在继承条件下才能使用
    • 构造方法:
      • this( ) //本类的构造
      • super( ) //父类的构造
2.3、方法重写
  • 重写都是方法的重写,和属性无关
  • 方法重写只能是非静态方法,所以静态方法和非静态方法的区别很大

静态方法是不能被重写的,如下例子:

package com.joywon.oop2;


public class Application {
    public static void main(String[] args) {
        //静态方法 的调用只和左边,定义的数据类型有关
        A a = new A();
        a.test();

        //父类的引用指向子类
        B b = new A();
        b.test();
    }
}
package com.joywon.oop2;

public class A extends B{
    public static void test(){
        System.out.println("A.test()");
    }
}
package com.joywon.oop2;

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

非静态方法的重写,如下例子:

package com.joywon.oop2;


public class Application {
    public static void main(String[] args) {
        A a = new A();
        a.test();

        // 父类的引用,指向子类的类型
        B b = new A(); //子类重写了父类的方法
        b.test();
    }
}
package com.joywon.oop2;

public class A extends B{
    public void test(){
        System.out.println("A.test()");
    }
}
package com.joywon.oop2;

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

重写在idea中的标志

在这里插入图片描述

小修改一下:

package com.joywon.oop2;

public class A extends B{
    //将方法名改为test1,这样的话就没有重写父类B的test方法
    public void test1(){
        System.out.println("A.test()");
    }
}
B.test()
B.test()
  • 重写总结:
    • 需要有继承关系,子类重写父类的方法
    • 方法名必须相同
    • 参数列表必须相同
    • 修饰符:范围可以扩大但不能缩小:public > protected > default > private
    • 抛出异常:范围:**可以被缩小但不能扩大:**ClassNotFoundException > Exception(大)
  • 为什么要重写:
    • 父类的功能,子类不一定需要,或者不一定满足(需要增加功能)

3、多态

  • 多态存在的条件
    • 有继承关系
    • 子类重写父类方法
    • 父类引用指向子类对象
  • 注意:多态是方法的多态,属性没有多态
  • instanceof(类型转换)引用类型,判断一个对象是什么类型

4、其他

4.1 、instanceof
  • 判断两个类是否存在父子关系
package com.joywon.oop2;


public class Application {
    public static void main(String[] args) {
        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object o = new Student();

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

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

        Student s = new Student();
        System.out.println(s instanceof Object);
        System.out.println(s instanceof Person);
        System.out.println(s instanceof Student);
        //System.out.println(s instanceof Teacher); //编译报错
        //System.out.println(s instanceof String); //编译报错
    }
}
package com.joywon.oop2;

public class Person {

}
package com.joywon.oop2;

public class Student extends Person {

}
package com.joywon.oop2;

public class Teacher extends Person{
}
true
true
true
false
false
==================
true
true
true
false
==================
true
true
true
4.2、类型转换
package com.joywon.oop2;


public class Application {
    public static void main(String[] args) {
        Person test = new Student();
        ((Student)test).s();
        // 相当于
        Student test2 = (Student) test;
        test2.s();
    }
}
package com.joywon.oop2;

public class Student extends Person {
    public void s(){
        System.out.println("Student");
    }
}
package com.joywon.oop2;

public class Person {
    public void p(){
        System.out.println("Person");
    }
}
Student
Student
4.2、static关键字
package com.joywon.oop2;


public class Application {
    //匿名模块常用于 赋初始值
    {
        System.out.println("匿名代码块");
    }
    // 静态方法最先加载,和类一同加载(只执行一次)
    static{
        System.out.println("静态代码块");
    }
    public Application(){
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Application app1 = new Application();
        System.out.println("==========");
        Application app2 = new Application();
    }
}
静态代码块
匿名代码块
构造方法
==========
匿名代码块
构造方法

静态导入包

产生一个随机数

  • 没有导入包时,调用java默认的方法需要写全称:Math.random()
package com.joywon.oop2;


public class Application {
    public static void main(String[] args) {
        System.out.println(Math.random());
    }
}
  • 静态导入包
package com.joywon.oop2;

import static java.lang.Math.random;
public class Application {
    public static void main(String[] args) {
        System.out.println(random());
    }
}

(五)抽象类和接口

类是 单继承,接口可以多继承

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范

1、抽象类 abstract

package com.joywon.oop2;

// 方法是abstract,类必须是abstract
public abstract class Application {
    // abstract,抽象方法,只有方法名字,没有方法的实现
    public abstract void function();

    public void function2(){
        System.out.println("普通方法");
    }
    
    // 1、不能new这个抽象类,只能靠子类取实现它
    // 2、抽象类中可以写普通类的方法
    // 3、抽象方法必须在抽象类中
}

2、接口 implements

  • 接口就是规范,定义是一组规则,如什么时间干什么事
  • 接口的本质是契约,就像法律一样,制定后必须遵守

接口的实现

package com.joywon.jiekou;

public interface UserService {
    //常量 public static final int age = 10;
    int age = 10;
    
    // 实际上是公共抽象方法 public abstract void add(String name)
    void add(String name);
    void delete(String name);
    void update(String name);
    void search(String name);
}
package com.joywon.jiekou;

// 一个类要去实现一个接口,实现接口就要重写它的方法
// 最标准的写法public class UserServiceImpl implements UserService
public class UserServiceImpl implements UserService{
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void search(String name) {

    }
}

借口如何实现多继承呢

  • 继承TimeService 和 UserService
package com.joywon.jiekou;

public interface TimeService {
    void time();
}
package com.joywon.jiekou;

// 一个类要去实现一个接口,实现接口就要重写它的方法
// UserService, TimeService
public class UserServiceImpl implements UserService, TimeService{
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void time() {

    }

    @Override
    public void search(String name) {

    }
}

接口作用:

  1. 约束作用
  2. 定义一些方法,让不同人实现
  3. 接口不能被实例化,接口中没有构造方法
  4. implements可以实现多个接口

(六)内部类及实战

  • 内部类:类中还有一个类
package com.joywon.lei;

public class Application {
    public static void main(String[] args) {
        // 外部类直接通过new创建对象
        Outer outer = new Outer();
        // 内部类需通过外部类的对象来new对象
        Outer.Inner inner = outer.new Inner();
        inner.in();
    }
}
package com.joywon.lei;

public class Outer {
    public void out(){
        System.out.println("这是个外部类方法");
    }

    public class Inner{
        public void in(){
            System.out.println("这是个内部类方法");
        }
    }
}
这是个内部类方法
  • 外部类2:
package com.joywon.lei;

public class Application {
    public static void main(String[] args) {
        Test test = new Test();
        test.show();

        UserService userService = new UserService(){
            @Override
            public void show() {
                System.out.println("222");
            }
        };
        userService.show();
    }
}

class Test{
    public void show(){
        System.out.println("111");
    }
}

interface UserService{
    void show();
}

(七)异常处理 Exception

1、异常体系结构

  • java把异常当作对象来处理,并定义一个基类 java.lang.Throwable作为所有异常的超类
  • 在java api中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception

在这里插入图片描述

2、异常处理机制

  • 抛出异常
  • 捕获异常
  • 异常处理5个关键字
    • try、catch、finally、throw、throws
    • try:异常捕获块
    • catch:有异常时执行
    • finally:无论如何,程序都会执行
    • throw:主动抛出异常,常用于方法中
    • throws:将方法的异常抛出(抛到更高一级)
package com.joywon.exception;

public class Exception {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;
        try {
            System.out.println(a/b);
        }catch (java.lang.Exception e){  // 捕获最大的异常
            System.out.println(e);
        }finally {
            System.out.println("finally");
        }
    }
}

java.lang.ArithmeticException: / by zero
finally
  • 捕获多个异常要遵循从小到大原则
package com.joywon.exception;

public class Exception {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;
        try {
            System.out.println(a / b);
        } catch (Error error) {
            System.out.println("Error:" + error);
        } catch (java.lang.Exception exception) {
            System.out.println("Exception:" + exception);
        } catch (Throwable throwable) {
            System.out.println("Throwable:" + throwable);
        } finally {
            System.out.println("finally");
        }
    }
}
Exception:java.lang.ArithmeticException: / by zero
finally
  • 快捷键生成异常处理语句:ctrl+alt+t

在这里插入图片描述

package com.joywon.exception;

public class Exception {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;

        try {
            System.out.println(a/b);
        } catch (java.lang.Exception e) {
            throw new RuntimeException(e);
        } finally {
            System.out.println("finally");
        }
    }
}
finally
Exception in thread "main" java.lang.RuntimeException: java.lang.ArithmeticException: / by zero
	at com.joywon.exception.Exception.main(Exception.java:11)
Caused by: java.lang.ArithmeticException: / by zero
	at com.joywon.exception.Exception.main(Exception.java:9)

3、方法中抛出异常 throw

package com.joywon.exception;

public class Exception {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;

        new Exception().test(1,0);
    }

    public void test(int a, int b){
        if (b == 0){
            throw new ArithmeticException(); // 主动抛出异常(方法中)
        }
    }
}
Exception in thread "main" java.lang.ArithmeticException
	at com.joywon.exception.Exception.test(Exception.java:13)
	at com.joywon.exception.Exception.main(Exception.java:8)

4、方法上抛出异常 throws

package com.joywon.exception;

public class Exception {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;

        // 主程序需要用try-catch捕获方法的异常
        try {
            new Exception().test(1,0);
        } catch (java.lang.Exception e) {
            throw new RuntimeException(e);
        } finally {
            System.out.println("finally");
        }
    }

    public void test(int a, int b) throws java.lang.Exception {  // 将方法中存在的异常抛出给主程序
        if (b == 0){
            throw new ArithmeticException();
        }
    }
}
Exception in thread "main" java.lang.RuntimeException: java.lang.ArithmeticException
	at com.joywon.exception.Exception.main(Exception.java:11)
Caused by: java.lang.ArithmeticException
	at com.joywon.exception.Exception.test(Exception.java:19)
	at com.joywon.exception.Exception.main(Exception.java:9)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值