JAVA基础05:面向对象

JAVA基础05:面向对象

  1. 初识面向对象

  2. 方法回顾和加深

  3. 对象的创建分析

  4. 面向对象三大特性

  5. 抽象类和接口

  6. 内部类及OOP实战

面向过程 & 面向对象

  • 面向过程思想

    • 步骤清晰简单,第一步做什么,第二步做什么

    • 面对过程适合处理一下较为简单的问题

  • 面向对象思想

    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。

    • 买那些对象适合处理复杂的问题,适合处理需要多人协作的问题

    • 对于描述复杂的事务,为了宏观把控,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理

什么是面向对象

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

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

  • 抽象

  • 三大特性

    • 封装

    • 继承

    • 多态

  • 从认识的角度考虑是先有对象后有类。对象,是具体的事务。类,是抽象的,是对象的抽象

  • 从代码运行角度考虑是先有类后有对象。类是对象的模板

回顾方法的定义

视频名称:面向对象02回顾方法的定义


  • 方法的定义

    • 修饰符

    • 返回类型

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

      }
       /*
       * @Description
       * @Date 11:05 2020/11/18
       * @Param []
       * @return java.lang.String
       * 修饰符 返回值类型 方法名(参数){
       * //方法体
       * return 返回值 ;}
       **/
       public String sayHello(){
           return "hello,world";
      }
    //   非静态方法
       public void say(){
           System.out.println("学生说话了!");
      }

       public int max(int a,int b){
           return a>b ?a:b;//三元运算符
      }

    }

     

    • break 和 return的区别

      • break结束循环

      • return代表方法结束,返回值类型与方法类型一致

    • 方法名:注意规范,见面知意

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

    • 异常抛出

      public void readFile(String file) throws IOException{
           
      }
    //throws 抛出异常
  • 方法调用

    视频名称:面向对象03回顾方法的调用


    • 静态方法(static修饰)

    • 非静态方法

    package com.learn.oop.day05;

    /**
    * @author bcy
    * @PackeageName com.learn.oop.day05
    * @File Student
    * @date 2020/11/6 17:55
    * @description :
    */
    //类
    public class Student {
    //   main方法
       public static void main(String[] args) {

      }
       //静态方法 static 和类一起加载
      public static void say(){
          System.out.println("学生说话了!");
      }
       //非静态方法 对象创建之和才存在
      public void readBook(){
          System.out.println("学生在看书!");
      }

    }

    package com.learn.oop.day05;

    /**
    * @author bcy
    * @PackeageName com.learn.oop.day05
    * @File Demo02
    * @date 2020/11/18 11:15
    * @description :
    */
    public class Demo02 {

       public static void main(String[] args) {
           //静态方法直接调用
           Student.say();
           //非静态方法需要先实例化,然后调用
           Student student = new Student();
           student.readBook();
      }
    }

     

    • 形参和实参

      public class Demo03 {
         public static void main(String[] args) {
             int add = Demo03.add(1, 2);//1,2 是实参
             System.out.println(add);
        }
         
         public static int add(int a,int b){ //a,b 是形参
             return a+b;
        }
      }

       

    • 值专递和引用传递 知乎链接

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

       public static void change(int a){
           a=10;
      }
    }
    //引用传递 本质还是值传递
    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);// bcy
      }

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

    class Person {
       String name;
    }

     

    • this关键字():代指当前类

 

类与对象的关系

面向对象04:类与对象的创建


  • 类是一种抽象的数据类型,它是对某一类事物整体描述、定义,但是并不能代表某一个具体的事物

    • 动物、植物、手机、电脑

    • Person类型,Pet类,Car类等,这些类是用来描述定义一类具体事物应该具备的特点和行为

  • 对象是抽象概念的具体实例

    • 张三就是一个具体的实例,张三家里的旺财就是狗的一个具体实例

    • 能够体现出特点,展现出功能的具体的实例,而不是抽象概念

创建与初始化对象

  • 使用new关键字创建对象

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

}

public class Application {
   //类:抽象化的 实例化
   //类实例化后返回一个自己的对象
   //student对象就是一个student类的具体实例

   public static void main(String[] args) {
       Student xm = new Student();
       System.out.println(xm.name);//null
       System.out.println(xm.age);//0
       xm.name="小明";
       xm.age=11;
       System.out.println(xm.name);//小明
       System.out.println(xm.age);// 11

       Student xh = new Student();
       System.out.println(xh.name);//null
       System.out.println(xh.age);//0
       xh.name="小红";
       xh.age=12;
       System.out.println(xh.name);//小红
       System.out.println(xh.age);//12

  }
}

视频:面向对象05构造器详解


  • 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认初始化以及对类中构造器的调用

//class文件中
public class Person {
   public Person() {//隐藏构造器方法
  }
}

 

  • 类中的构造器也称为构造方法,是进行创建对象时候必须要调用的,并且构造器有以下俩个特点

    • 必须合类型的名字相同

    • 必须没有返回类型,也不能写void

  • 构造器必须要掌握

public class Person {
   String name;
////   无参数构造器
//   public Person(){
//
//   }
////   有参构造器
//   public Person(String name){
//       this.name = name;
//   }

   // alt + insert 快捷键生成构造器
   // 选择 Constructor->选择 ok 生成有参构造器
   // 选择 Constructor->选择 select none 生成无参构造器

   // 1.使用new关键字,本质实在调用构造器
   //2.构造器用来初始化值
   public Person() {
  }
   // 有参构造器:一旦定义了有参构造器,无参构造器必须显示定义
   public Person(String name) {
       this.name = name;//this.name 指类的属性name name指形参name
  }
}
/*
* @Description
* @Date 17:29 2020/11/18
* @Param
* @return
* 测试代码
    Person person = new Person();
       System.out.println(person.name);//null 走无参数构造器
       Person person1 = new Person("bcy");
       System.out.println(person1.name);//bcy 走有参构造器
* 构造器
* 1.和类名相同
* 2.没有返回值
* 作用
* 1、new的本质是调用构造器方法
* 2、初始化对象的值
* 注意点
* 1、定义有参构造器后,无参数构造器必须显示定义
* alt+insert 快捷键生成构造器
* this。
**/
public class Application {
   //类:抽象化的 实例化
   //类实例化后返回一个自己的对象
   //student对象就是一个student类的具体实例

   public static void main(String[] args) {

       Person person = new Person();
       System.out.println(person.name);//null 走无参数构造器

       Person person1 = new Person("bcy");
       System.out.println(person1.name);//bcy 走有参构造器

  }
}

视频:面向对象06:创建对象内存分析


 

 

视频:面向对象07:简单小结类与对象


/*

1.类与对象区别
   类是一个模板,对象是一个具体的实例
2.方法
   定义、调用
3.对象的引用
   引用类型: 基本类型(8种)
   对象是通过引用来操作的:栈--> 堆
4.属性:字段field 成员变量
   默认初始化:
       数字:0 0.0
       char: u0000
       boolean:false
       引用: null
5.对象的创建和使用
   - 必须是使用new关键字创建对象 构造器 Person ks = new person
   - 对象的属性 ks.name;
   - 对象的方法 ks.sleep();

6.类
   静态的属性 属性
   动态的行为 方法
**/

视频:面向对象08:封装详解


封装

  • 该露的露,该藏的藏,

    • 程序设计要追求“高内聚 低耦合”

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

    • 低耦合:暴雷少量的方法给外部使用

  • 封装(数据的隐藏)

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

    • 属性私有 get、set

public class Student {

   private String name;// private 私有
   private int id;
   private char sex;
   private int age;

   //获取这个属性值
   public String getName() {
       return name;
  }
   //设置属性值
   public void setName(String name) {
       this.name = name;
  }

   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) {
      // 可以对参数进行合法性校验
       if(age>120 || age<0){
           this.age = 3;
      }else {
           this.age=age;
      }
  }
}

public class Application {

   public static void main(String[] args) {

       /*
        封装的作用
        1.提高程序的安全性,保护数据
        2、隐藏代码的实现细节
        3、统一接口
        4、系统可维护行增加了
        5、快捷键 alt+insert -> getter and setter ->ok
       **/
       Student s1 = new Student();
       s1.setName("bcy");
       System.out.println(s1.getName());

       s1.setAge(999);
       System.out.println(s1.getAge());
  }
}

 

视频:面向对象09:什么是继承


继承

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

  • extends的意思是扩展。子类是父类的扩展

  • Java中类的继承都是单继承,没有多继承

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

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

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

//父类 基类
//   java中所有类都直接或者间接默认继承object类
public class Person {

   public int money = 10_0000_0000;

   private int age;

   public void say(){
       System.out.println("说了一句话");
  }

   public int getAge() {
       return age;
  }

   public void setAge(int age) {
       this.age = age;
  }
}
// 派生类
public class Student extends Person{
   //子类会继承父类的所有方法
   //ctrl + H 打开继承树
}

// 派生类

public class Teacher extends Person {
}

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

视频:面向对象10:Super详解


 

  • object类

  • super

public class Person {
   public Person() {
       System.out.println("Person无参数构造器执行了!");
  }
   protected String name="父类";
   public void print(){
       System.out.println("Person");
  }
}

public class Student extends Person{
   //子类会继承父类的所有方法
   //ctrl + H 打开继承树
   //隐藏代码:调用了父类的无参构造器
   //调用父类的构造器,必须要在子类构造器的第一行
   //实例化子类的实际顺序是: Person -> Student 默认调父类构造器,在调子类构造器
   public Student() {
       System.out.println("Student无参数构造器执行了!");
  }
   public Student(String name) {
       this.name = name;
  }
   private String name = "学生类";
   public void test(String name){
       System.out.println(name);//变量 name
       System.out.println(this.name);// 本类的属性 name 学生类
       System.out.println(super.name);//父类的属性 name 父类
  }
   public  void print(){
       System.out.println("Student");
  }
   public void test02(){
       print();//Student
       this.print();//Student
       super.print();// Person
  }
}
public class Application {
   public static void main(String[] args) {
       new Student("bcy");
  }
}
  • super注意点:

    • super调用父类的构造方法,必须在构造方法的第一行

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

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

  • vs this

    • 代指的对象不同

      • this 本身调用者这个对象

      • super 代指父类的引用

    • 前提

      • 没有基础也可以使用

      • 只能继承条件下可以使用

    • 构造方法

      • this(); 本类的构造

      • super();父类的构造

 

  • 方法重写

视频:面向对象11:方法重写


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

   public void say(){
       System.out.println("B----->say");
  }
}
//继承
public class A extends B{
   public static void test(){
       System.out.println("A====>test!");
  }

   @Override //注解:有功能的注释!
   public void say() {
//       super.say();
       System.out.println("A------>say");
  }
}
public class Application {
   
   public static void main(String[] args) {
       A a = new A();
       a.test();//A====>test!
       a.say();//A------>say

       B b = new A();//父类的引用指向子类 方法的调用,只和左边定义的数据类型有关
       b.test();//B====>test!
       b.say();//A------>say
  }
/*
重写:需要有继承关系,子类重写父类方法!
   1、方法名必须相同
   2、参数列表必须相同
   3、修饰符:范围可以扩大 public > Protected > Default > Private
   4、抛出的异常:范围,可以被缩小,但不能扩大: classNotFoundException <--> Exception
重写,子类的方法和父类的一致:方法体不同

为什么需要重新:
   1、父类的功能,子类不一定需要,或者不一定满足!
   2、快捷键:alt+insert :override
**/
}

视频:面向对象12:什么是多态


  • 多态

    • 同一方法可以根据发送对象不同而采用多种不同的行为方式

    • 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多

    • 多态存在条件

      • 有继承关系

      • 子类重写父类方法

      • 父类引用指向子类对象

    • 注意:多态是方法的多态,与属性无关

    • instanceof(类型转换) 引用类型

视频:面向对象13:instanceof和类型转换


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

public class Student extends Person{

   @Override
   public void run() {
       System.out.println("son");
  }

   public void eat(){
       System.out.println("eat");
  }

   public void go(){
       System.out.println("go");
  }
}

public class Teacher extends Person {
}
public class Application {
   public static void main(String[] args) {

//       System.out.println(X instanceof Y); 能不能编译通过,看X类型与Y类型是否存在继承关系

       // Object String
       // Object Person Student
       // Object Person Teacher
       Object object = new Student();
       System.out.println(object instanceof Student);//true
       System.out.println(object instanceof Person);//true
       System.out.println(object instanceof Object);//true
       System.out.println(object instanceof Teacher);//false 与Teacher无关
       System.out.println(object instanceof String);//false
       System.out.println("=======================================");

       Person person = new Student();
       System.out.println(person instanceof Student);//true
       System.out.println(person instanceof Person);//true
       System.out.println(person instanceof Object);//true
       System.out.println(person instanceof Teacher);//false 与Teacher无关
//       System.out.println(person instanceof String); //编译报错!

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

       System.out.println("=======================================");
//       instanceof和类型转换总结
//1、父类引用指向子类的对象
//2、把子类转化为父类,向上转型
//3、把父类转化为子类,向下转型:强制转换
//4、方便方法的调用,减少重复代码!简介

//     类型之间转换 父类(高) 子类(低) 低转高可以自动转化
//       父类 -> 子类 需要强制转化
//       子类 -> 父类 可以直接转换 可能丢失自己本来的方法
       //高                 //低
       Person stu_1 = new Student(); //1、父类(Person)引用指向子类(Student)的对象
//       stu_1.go(); 父类,无法直接调用子类独有的go方法
//       强制转化为子类,可以调用子类独有go方法

       //强制转化:写法1
       Student stu_2 =(Student) stu_1; //3、把父类(Person)转化为子类(Student),向下转型:强制转换
       stu_2.go();
       //强制转化:写法2
      ((Student) stu_1).go(); //与上述语句,作用相同

       Person person1 = stu_1;
       person1.run();  //子类 -> 父类,可能丢失自己本来的方法

  }
}

视频:面向对象14:static关键字详解

非静态方法随着类加载时加载

//1、静态方法可以调用静态方法
//2、非静态方法可以调用静态方法
//3、静态方法不可以调用非静态方法

public class Person {
  {
       System.out.println("匿名代码块"); //在构造器之前执行,随着类实例化再次执行
  }

   static {
       System.out.println("静态匿名代码块");//在构造器之前执行,仅执行一次
  }
   public Person(){
       System.out.println("构造方法");
  }

   public static void main(String[] args) {
       Person person = new Person();
       System.out.println("==============");
       Person person1 = new Person();
       System.out.println("==============");
       Person person2 = new Person();
  }
}
//静态匿名代码块
//匿名代码块
//构造方法
//==============
//匿名代码块
//构造方法
//==============
//匿名代码块
//构造方法

视频:面向对象15:抽象类


  • 抽象类

    • abstract 修饰符可以用来修饰方法也可以修饰类。如果修饰方法,那么该方法就是抽象方法。如果修饰类,那么该类就是抽象类

    • 抽象类中可以没有抽象方法,有抽象方法的类一定要声明称抽象类

    • 抽象类,不能使用new关键来创建,它是用来让子类继承的

    • 抽象方法,只有方法声明,没有方法实现,它是用来让子类实现的

    • 子类继承抽象类,那么必须时间抽象类没有实现的抽象方法,否则该子类也需要声明为抽象类

    //abstract 抽象类:类 extends 单继承  
    public abstract class Action {
    //   约束,其他人帮忙实现方法
    //   abstract 抽象方法,只有方法名字,没有方法实现
       public abstract void doSomething();
       
       public void test(){
           System.out.println("Test");
      };
       
       /*
       * @Description  
       1、不能new出来,只能靠子类实现:约束
       2、抽象类可以写普通方法
       * 3、抽象类必须在抽象类中
       *
       *
       * 思考题:
       * 1、抽象类中是否存在构造器?
       *
       * 2、抽象类存在的意义?
       *   答:利于继承,提高开发效率
       **/
       
    }
    • 1、抽象类中是否存在构造器?

      • 答:存在

    • 2、抽象类存在的意义?

      答:

      • 可以用来初始化抽象类内部声明的通用变量,并被各种实现使用。

      • 另外,即使没有提供任何构造函数,编译器将为抽象类添加默认的无参数的构造函数,没有的话子类将无法编译,因为在任何构造函数中的第一条语句隐式调用super (),Java中默认超类的构造函数。

      • 子类对象实例化的时候,满足先执行父类构造,再执行子类构造的顺序

视频:面向对象16:接口的定义与实现


  • 接口

    • 普通类:只有具体实现

    • 抽象类:具体实现和规范(抽象方法)都有!

    • 接口:只有规范,无自己的实现方法

    • 接口就是规范,定义的是一组规则,体现现实世界中,“如果你是。。。必须能。。。”的思想。

    • 接口的本质是契约,就像我们的法律一样,制定好后大家都准守

    • OO的精髓,是对象的抽象,最体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语音,就是因为设计模式所研究的,实际上就是如何合理的去抽象。

    • 声明类的关键字是 class 声明接口的关键字是interface

    声明类的关键字是class 声明接口的关键字是 interface
     package com.opp.day09;

    public interface UserService {

    //   接口中定义的属性都是常量 public static final 静态常量一般接口中不定义
       int AGE=90;

    //   接口中定义的方法都是抽象的 public abstract
       void add(String name);
       void delete(String name);
       void update(String name);
       void query(String name);
    }


    package com.opp.day09;

    public interface TimeService {
       void timter();
    }
    package com.opp.day09;
    //抽象类:extends
    //类 可以实现接口 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 timter() {

      }
    }
  • 总结

    • 接口作用: 1、约束

    • 2、定义一些方法,让不同的人实现

    • 3、public abstract 修饰方法

    • 4、public static final 修饰属性

    • 5、接口不能被实例化,(接口中午构造方法)

    • 6、implement 可以实现多个接口

    • 7、必须重新接口中的方法

视频:面向对象17:N种内部类


  • 内部类

    • 内部类及就是一个类的内部定义一个类,比如A类中定义一个B类,那么B类相对A来说就是内部类,而A对B来说就是外部类了

    • 成员内部类

      package com.opp.day10;
      public class Outer {
         private int id=10;
         public void sout(){
             System.out.println("这是外部类");
        }
        public class Inner{
             public void sout(){
                 System.out.println("这是内部类");
            }
        }
      }
      //一个java类中可以有多个class,但只能有一个public class
      class A {
      }

      静态内部类

      public class Outer {
         private int id=10;
         public void sout(){
             System.out.println("这是外部类");
        }
        public class Inner{
             public void sout(){
                 System.out.println("这是内部类");
            }
        }
         public static class Inner2{
             public void sout(){
                 System.out.println("这是内部类");
            }
        }
      }

      局部内部类

      public class Outer2 {
      //   局部内部类
         public void method(){
             class Inner{
                 public void in(){
                }
            }
        }
      }

       

    • 匿名内部类

      public class TestJava {
         public static void main(String[] args) {
      //       没有名字初始化,不用将实例保存到变量中
             new Apple().eat();//匿名内部类
        }
      }

      class Apple{
         public void eat(){
             System.out.println("eat");
        }
      }

       

    •  

posted @ 2020-11-30 10:44  蓬莱大侠  阅读(73)  评论(0)    收藏  举报