面向对象

面向对象

什么是面向对象

面向过程与面向对象

  • ⾯向过程就是分析出解决问题的步骤,然后⼀步⼀步实现,在使⽤的时候分步调⽤即可;
  • ⾯向对象就是把问题事务分解成各个对象,建⽴对象的⽬的不是为了完成⼀个步骤,⽽是描述某个事物在整个解决问题步骤
    中的⾏为。

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

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

抽象

三大特性:- 封装 - 继承 -多态

回顾方法的定义和调用

方法的定义

  • 修饰符

  • 返回类型

  • break(跳出switch,结束循环)和return的区别

  • 方法名

  • 参数列表(参数类型,参数名)...

  • 异常抛出

package com.oop.demo01;

import java.io.IOException;

//Demo01  类
public class Demo01 {
    //main  方法
    public static void main(String[] args) {

    }
    /*
    修饰符  返回值类型   方法名(...){
        //方法体
        return 返回值:
    }
     */
    //return 结束方法,返回一个结果
    //break 跳出switch,结束循环
    public String sayhello(){
        return "hello,world";
    }
    public void print(){
        return;
    }
    public int max(int a,int b){
        return a>b ? a : b;  //三元运算符
    }

    //数组下标越界:Arrayindexoutofbounds
    public void readFile(String file) throws IOException{

    }
}

方法的调用

  • 静态方法
  • 非静态方法
  • 形参和实参
  • 值传递和引用传递
  • this关键词
package com.oop.demo01;

//学生类
public class Student {
    // 非静态方法
    public void say(){
        System.out.println("学生说话了");
    }
}

package com.oop.demo01;

public class Demo02 {
    //静态方法  static   可以直接通过类名调用

    public static void main(String[] args) {
        //非静态方法
        //实例化这个类 new
        //对象类型  对象名=对象值

        Student student = new Student();
        student.say();
    }

    //和类一起加载的
    public static void a(){
        //b();
    }
    //类实例化  之后才存在的
    public void b(){

    }
}


package com.oop.demo01;

public class Demo03 {
    public static void main(String[] args) {
        //实际参数和形式参数的类型相对应
        int add = Demo03.add(1,1);
        System.out.println(add);
    }

    public static int add(int a,int b){
        return a+b;
    }
}

package com.oop.demo01;

//值传递
public class Demo04 {
    public static void main(String[] args) {
        int a = 1;
        System.out.println(a);
        Demo04.change(a);
        System.out.println(a);
    }

    //返回值为空
    public static void change(int a){
        a=10;
    }
}

package com.oop.demo01;

//引用传递:对象,本质还是值传递
public class Demo05 {
    public static void main(String[] args) {
        Person person = new Person();

        System.out.println(person.name);//null

        Demo05.change(person);
        System.out.println(person.name);
    }
    public static void change(Person person){
        //person是一个对象,指向的是-->Person person = new Person();这是一个具体的人,可以改变属性
        person.name="李";
    }

}

class Person{
    String name;//null


}


类与对象的创建

  • 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物
  • 对象是抽象概念的具体实例
  • 使用new关键字创建对象
  • 掌握构造器
package com.oop.demo02;

import com.oop.demo02.Person;

//一个项目应该只存在一个main方法
public class Application {

    public static void main(String[] args) {
        //new 实例化了一个对象
        Person person = new Person("li");

        System.out.println(person.name);//null


//        //类:抽象的,实例化
//        //类实例化后会返回一个自己的对象
//        //student对象就是Student类的一个实例
//        Student xiaoming = new Student();
//        Student wangqing = new Student();
//
//        xiaoming.name="小明";
//        xiaoming.age=18;
//
//        System.out.println(xiaoming.name);
//        System.out.println(xiaoming.age);
//
//        wangqing.name="王青";
//        wangqing.age=18;
//
//        System.out.println(wangqing.name);
//        System.out.println(wangqing.age);


    }

}
package com.oop.demo02;

//学生类
public class Student {

    //属性:字段
    String name;//null
    int age;//0

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

}

构造器详解

package com.oop.demo02;

public class Person {
    //一个类即使什么也不写,它也会存在一个方法
    //显示的定义构造器

    String name;

    //1.使用new关键字,本质是在调用构造器
    //2.用来初始化值
    public Person(){ }

    //有参构造:一旦定义了有参构造,无参就必须显式定义
    public Person(String name){
        this.name = name;
    }
    //alt+insert 生成构造器
}

/*
    public static void main(String[] args) {
            //new 实例化了一个对象
            Person person = new Person("li");

            System.out.println(person.name);//null
    }

    构造器:
        1.和类名相同
        2.没有返回值
    作用:
        1.new 本质在调用构造方法
        2.初始化对象的值
    注意点:
        1.定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造

      alt + insert

 */


创建对象内存分析

package com.oop.demo03;

public class Pet {
    public String name;
    public int age;

    //无参构造

    public void shout(){
        System.out.println("叫了一声 ");
    }

}

package com.oop.demo03;

import com.oop.demo03.Pet;

public class Application {
    public static void main(String[] args) {
        Pet dog = new Pet();
        dog.name = "贝贝";
        dog.age = 3;
        dog.shout();
        System.out.println(dog.name);
        System.out.println(dog.age);

        Pet cat = new Pet();

    }
}

简单小结类与对象

package com.oop;

public class Application {
 
    public static void main(String[] args) {
        /*
        1.类与对象
            类(抽象)是一个模板,对象是一个具体实例
        2.方法
            定义、调用!
        3.对象的引用
            引用类型:基本类型(8)
              对象是通过引用类型类操作的:栈-->堆
        4.属性:字段Field成员变量
            默认初始化:
                数字:  0   0.0
                char: u0000
                boolean:  false
                引用: null

            修饰符  属性类型  属性名 = 属性值
        5.对象的创建和使用
            -必须使用new关键字创造对象,构造器  Person li =new Person();
            -对象的属性  li.name
            -对象的方法  li.sleep()
        6.类
            静态的属性  属性
            动态的行为  方法

         封装、继承、多态
         */
    }
}

封装详解

  • “高内聚,低耦合”

高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;

低耦合:仅暴露少量的方法给外部使用

  • 封装(数据的隐藏)
    通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏

  • 属性私有,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方法

    //获得这个数据
    public String getName(){
        return this.name;
    }

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

    //alt + insert

    public char getSex() {
        return sex;
    }

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

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

    public int getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age>120 || age<0){ //不合理
            this.age = 3;
        }else {
            this.age = age;
        }

    }
}

package com.oop;

import com.oop.Demo04.Student;
/*
    封装
    1.提高程序的安全性,保护数据
    2.隐藏代码的实现细节
    3.统一接口
    4.增加系统的可维护
 */

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

        //判断是否是同一个方法:方法名、参数列表
        s1.setName("李明");
        System.out.println(s1.getName());
        s1.setAge(8);
        System.out.println(s1.getAge());

    }

}

什么是继承

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

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

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

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

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

  • 子类和父类之间,从意义上讲应该具有"is a"的关系.

  • object类

  • super

  • 方法重写

package com.oop.Demo05;

//在Java中,所有的类都直接或间接继承Object
//Person 人  父类
public class Person {
    //public  公共的
    //protected  受保护的
    //default   默认的
    //private   私有的
    private int money = 10000;
    public void say(){
        System.out.println("说了一句话");
    }

    public int getMoney() {
        return money;
    }
    public void setMoney(){
        this.money = money;
    }
}

package com.oop.Demo05;

//学生 is 人  :派生类,子类
//子类继承了父类,就会拥有父类的全部方法
public class Student extends Person {
    //ctrl + H
}

package com.oop.Demo05;


//老师 is 人  :派生类,子类
public class Teacher extends Person {

}

package com.oop;

import com.oop.Demo05.Person;

public class Application {
    private static Person student;

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

    }

}

Super详解

super注意点:
    1.super调用父类的构造方法,必须在构造方法的第一个
    2.super必须只能出现在子类的方法或构造方法中!
    3.super和this不能同时调用构造方法!

VS this:
    代表的对象不同:
        this: 本身调用这个对象
        super: 代表父类对象的引用
    前提
        this: 没有继承也可以使用
        super: 只能在继承条件下才可以使用
    构造方法
        this(): 本类的构造
        super(): 父类的构造
package com.oop.Demo05;

import javax.swing.*;

//在Java中,所有的类都直接或间接继承Object
//Person 人  父类
public class Person {
    public Person() {
        System.out.println("Person无参执行了");
    }

    protected String name ="Lzoro";
    public void print(){
        System.out.println("Person");
    }
}

package com.oop.Demo05;

//学生 is 人  :派生类,子类
//子类继承了父类,就会拥有父类的全部方法
public class Student extends Person {
    public Student() {
        //隐藏代码:调用了父类的无参构造
        super();//调用父类的构造器,必须要在子类构造器的第一行
        System.out.println("Student无参执行了");
    }

    private String name = "lijy";
    public void print(){
        System.out.println("Student");
    }
    public void test1(){
        print();//Student
        this.print();//Student
        super.print();//Person
    }
    public void test(String name){
        System.out.println(name);//索隆女朋友
        System.out.println(this.name);//lijy
        System.out.println(super.name);//lzoro
    }
}

package com.oop;

import com.oop.Demo05.Student;
import com.oop.Demo05.Person;


public class Application {

    public static void main(String[] args){
        Student student = new Student();
//        student.test("索隆女朋友");
//        student.test1();

    }

}

方法重写

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

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

为什么需要重写:
    1.父类的功能,子类不一定需要,或者不一定满足!
    Alt + Insert : override
package com.oop.Demo05;

//重写都是方法的重写,与属性无关
public class B {
    public static void test(){
        System.out.println("B>=test()");
    }
}

package com.oop.Demo05;

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

package com.oop;

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>=test()
B>=test()

package com.oop.Demo05;

//重写都是方法的重写,与属性无关
public class B {
    public void test(){
        System.out.println("B>=test()");
    }
}

package com.oop.Demo05;

public class A extends B{

    //Override 重写
    @Override //注解:用功能的注释
    public void test() {
        System.out.println("A>=test()");
    }
}

package com.oop;

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();//A

        //父类的引用指向了子类
        B b = new A();//子类重写了父类的方法
        b.test();//B

    }

}

输出:

A>=test()
A>=test()

什么是多态

即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多
多态注意事项:
    1.多态是方法的多态,属性没有多态
    2.父类和子类,有联系   类型转换异常!(ClassCastException!)
    3.存在条件:有继承关系,子类重写父类的方法,父类引用指向子类对象!  Father f1 = new Son();
      以下方法不能重写:
        1.static方法,属于类,它不属于实例
        2.final常量;
        3.private方法;
        
instanceof     (类型转换)引用类型
package com.oop.demo06;

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

package com.oop.demo06;

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

package com.oop;


import com.oop.demo06.Person;
import com.oop.demo06.Student;

public class Application {

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

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

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

        //对象能执行那些方法,主要看对象左边的类型,和右边关系不大!
        s2.run(); //son  子类重写了父类的方法,执行子类的方法
        s1.run();//son


    }


}

instanceof和类型转换

instanceof来判断两个类之间是否存在父子关系

package com.oop;


import com.oop.demo06.Person;
import com.oop.demo06.Student;
import com.oop.demo06.Teacher;

public class Application {

    public static void main(String[] args){

        //Object > String
        //Object > Person >Teacher
        //Object > Person >Student
        Object object = new Student();

        //System.out.println(X instanceof Y);能不能编译通过!

        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);//编译报错,person 和 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);//编译报错

    }


}

类型转换

类型之间的强制转换: 高转低 强制转换

低转高 直接转换

1.父类引用指向子类对象
2.把子类转化为父类,向上转型
3.把父类转换为子类,向下转型:强制转换
4.方便方法的调用,减少重复的代码
package com.oop.demo06;

public class Student extends Person{
    public void go(){

    }

}

package com.oop;


import com.oop.demo06.Person;
import com.oop.demo06.Student;
import com.oop.demo06.Teacher;

public class Application {

    public static void main(String[] args){
        //类型之间转换:父   子
        //高                低
        //子类转换为父类,可能会丢失自己本来的一些方法!
        Person obj = new Student();

        //student将这个对象转换为Student类型,我们就可以用Student类型的方法!
        ((Student)obj).go();
    }


}

static关键字详解

package com.oop.demo07;

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

package com.oop.demo07;

public class Student extends Person{
    private static int age;//静态的变量   多线程
    private double score;//非静态的变量
    public static void main(String[] args) {

    }
}

package com.oop.demo07;

//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Test {
    public static void main(String[] args) {
        System.out.println(random());
        System.out.println(PI);
    }
}

抽象类

抽象类用来描述一种类型应该具备的基本特征与功能, 具体如何去完成这些行为由子类通过方法重写来完成

即抽象方法指只有功能声明,没有功能主体实现的方法。
具有抽象方法的类一定为抽象类。

抽象类无法直接创建对象,只能被子类继承后,创建子类对象。

package com.oop.demo08;

//abstract 抽象类:类  expends  单继承  (接口可以多继承!)
public abstract class Action {

    //约束~ 有人帮我们实现
    //abstract,抽象方法,只有方法的名字,没有方法的实现
    public abstract void doSomething();

    //1.不能new这个抽象类,只能靠子类去实现:约束!
    //2.抽象类中可以写普通的方法
    //3.抽象方法必须在抽象类中
    //抽象的抽象:约束

}

package com.oop.demo08;

//继承抽象类的子类,需要重写父类的方法,除非子类同为抽象类
public class A extends Action{
    public void doSomething(){}
}

接口的定义与实现

关键字interface

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范,自己无法写方法
接口的作用:
    1.约束
    2.定义一些方法,让不同的人实现
    3.public abstract
    4.public static final
    5.接口不能实例化,接口中没有构造方法
    6.implements可以实现多个接口
    7.必须要重写接口中的方法  ctrl + i
package com.oop.demo09;

//interface 定义的关键字,接口都需要实现类 
public interface UserService {

    //常量   public static final
    int Age = 99;

    //接口中所有定义其实都是抽象的 public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);

}

package com.oop.demo09;

public interface TimeService {
    void Time();
}
package com.oop.demo09;

//抽象类 :expends
//类 可以实现接口  implements 接口
//实现了接口的类,就需要重写接口的方法
//多继承  利用接口实现多继承
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 query(String name) {

    }

    @Override
    public void Time() {

    }
}

N种内部类

内部类就是在一个类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类

内部类访问特点
            * 内部类可以直接访问外部类的成员,包括私有。
            * 外部类要访问内部类的成员,必须创建对象。
  • 成员内部类
定义在类内部的非静态类叫做成员内部类,在成员内部类中不能定义静态方法和变量(除了final修饰的除外),因为成员内部类是非静态的额,而在java中非静态的代码块不能定义静态方法和变量。
package com.oop.demo10;

public class Outer {
  private int id=10;
  public void out(){
      System.out.println("这是外部类的方法");
  }
  public class Inner{
      public void in(){
          System.out.println("这是内部类的方法");
      }
  
      //获得外部类的私有属性
      public void getID(){
          System.out.println(id);
      }
  }
}
package com.oop;
  
  
import com.oop.demo10.Outer;
  
	public class Application {
  
      public static void main(String[] args){
          Outer outer = new Outer();
  
          //通过这个外部类来实例化内部类
          Outer.Inner inner = outer.new Inner();
          inner.getID();//10
      }
  
  
  }
  • 静态内部类

    定义在类内部的静态类称为静态内部类。静态内部类可以访问外部类的静态变量和方法;在静态内部类中可以定义静态变量、方法、构造函数等;静态内部类通过“外部类.静态内部类”的方式来调用;
    
    
  • 局部内部类

    定义在方法中的类叫做局部内部类。当一个类只需要在某个方法中使用了某个特定的类时,可以通过局部类来优雅的实现
    
    package com.oop.demo10;
    
    public class Outer {
    
        //局部内部类
        public void method(){
            class Inner{
                public void in(){
    
                }
            }
        }
    
    }
    
  • 匿名内部类

    匿名内部类指通过继承一个父类或者实现一个接口的方式直接定义并使用的类。匿名内部类没有class关键字,这是因为匿名内部类直接使用new 生成一个对象的引用。
    
    package com.oop.demo10;
    
    public class Outer {
    
    }
    //一个Java类中可以有多个class类,但是有一个public class
    class A  {
    
    }
    
package com.oop.demo10;

public class Test {
    public static void main(String[] args) {
        //没有名字初始化类,不用将实例保存在变量中
        Apple apple = new Apple();

        UserService userService = new UserService(){
            @Override
            public void hello() {

            }
        };
    }
}
class Apple{
    public void eat(){
        System.out.println("it");
    }
}
interface UserService{
    void hello();
}
posted @ 2022-05-24 20:30  Lzoro  阅读(74)  评论(0)    收藏  举报