09.面对对象编程

面向对象编程

1、初识面向对象(object-oriented programming)

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

2、类和对象的关系

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

3、对象的创建分析

  • 使用new关键字创建对象

    classType objectName = new classType();
    
  • 使用new关键字创建的时候,除了分配内存空间外,还会调用构造器对对象的属性值进行初始化

  • 类的结构器也称为结构方法,是再进行创建对象的时候必须要调用的。

  • 构造器

    • 一个类有个默认的方法,该方法被称为构造方法,即构造器。
    • 特点
      • 和类名相同
      • 没有返回值
    • 作用
      • 初始化对象的属性值
    • 注意点
      • 定义有参构造器之后,要使用无参构造,必须显示的定义一个无参构造。
    //构造器定义例子。
    public class Person {//类
        String name;
        
        //无参构造器
        public Person(){}
       
        //有参构造器
        public Person(String name){
            this.name = name;
        }
        //alt+insert,快捷生成构造器等(idea上可用)
    }
    

4、面向对象三大特征

一、封装

1.为什么要封装

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

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

2.如何封装

​ 使用属性私有(private)、方法get、set实现,实例如下

package com.oop.demo04;

public class Student {
    //属性私有
    private String name ;
    private char sex;
    //提供一些可以操作这些属性的方法!public 的 get、set方法
    
    //get 获得名字数据
    public String getName(){
        return name ;
    }
    //set 设置名字数据
    public void setName(String name){
        this.name = name;
    }
    
    //get 获得性别数据
    public char getSex(){
        return sex;
    }
	//set 设置性别数据,并对性别做限制
    public void setSex(char sex){
        if (sex == '男' || sex == '女')
        {
            this.sex = sex;
        }else {
            System.out.println("你是太监吗");
        }
    }
}
//idea中alt+insort可以快速创建set、get方法。

3.封装的特点:

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

二、继承

1、继承的概念及用法

  • 继承的本质是对一批类的抽象,如下图对人这一类抽象出学生类、教师类。
  • 继承是类与类的一种关系,其中人称为父类(基类),学生、教师称为子类(派生类)。类与类之间的关系除继承外,还要组合、依赖、聚合等。
  • Java中只有单继承,无多继承。即:一个父类可以有多个子类,而一个子类只能有一个父类

  • java中子类继承父类使用extend关键字,伪代码如下:

    public class Person {
        private int money = 10_0000_0000;//私有属性
        public String name;
        public void say(){
             System.out.println("说了一句话");
        }
        public int getMoney(){
            return money;
        }
        public void setMoney(int money){
            this.money = money;
        }
    }//父类,人
    public class Student extends Person {}//子类,教师
    public class Student extends Person {}//子类,学生
    //idea中ctrl+H可以看类的上下层关系
    
  • java中子类拥有父类的所有公有属性和公有方法

  • java中所有的类,都默认直接或者间接基础Object类

  • 被final修饰的类是不可以被继承的。

2、super、this

  • super()调用父类的构造方法,默认存在于子类构造方法的第一个。
  • super只能出现在子类的方法中。
  • this:表示自身类
  • super:表示父类

3、方法重写

  • 需要有继承关系,子类重写父类的方法
  • 方法名、参数列表必须相同,且不能是静态方法
  • 修饰符的范围可以扩大不能缩小:public > protected > default > private
  • 抛出的异常范围可以缩小不能扩大
  • 重写是方法重写,属性没有重写

三、多态

1、多态的概念

  • 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
  • 一个对象的实际类型是确定的,但指向该对象的引用的类型可以有多种(父类、有关系的类)

2、多态的存在条件

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象

3、注意事项

  • 多态是指方法的多态,属性没有多态

4、代码实现

//父类:人
public class Person {
    public  void test(){
        System.out.println("person");
    }
}
//子类:学生
public class Student extends Person{

    public  void test() {
        System.out.println("student");
    }
}
//测试类
public class Application {
    public static void main(String[] args) {
        //一个对象的实际类型是确定的,指向该对象的引用类型可以是多种的
        //同一方法根据发送对象的不同而采用不同的行为方式
        Student student1 = new Student();
        student1.test();
        Person student2 = new Student();
        student2.test();
        Person student3 = new Person();
        student3.test();
    }
}
/*
执行结果如下:

student
student
person
*/

5、instanceof、static、类型转化、代码块

  • instanceof:

    该运算符前一个操作符是一个引用变量,后一个操作符通常为一个类(可以是接口),用于判断前面得对象是否是后面得类或者其子类,是则返回ture,否则返回false。【注:若前者与后者没有关系编译器报错】

  • static:

    被static修饰的属性和方法是和类一起被加载的,再当前类中可以直接被调用,不用new对象。

    package com.oop.demo07;
    
    public class Person {
        public static int age;
        public double money;
    
        public static void main(String[] args) {
            System.out.println(Person.age);//直接调用
            Person s1 = new Person();
            System.out.println(s1.money);//new对象调用
        }
    }
    
  • 代码块、构造方法的执行顺序

    静态代码块-->匿名代码块-->构造方法;其中静态代码块只执行一次。

    package com.oop.demo07;
    
    public class Student {
        public Student() {
            System.out.println("构造方法");
        }
        //可以用于赋初始值
        {
            System.out.println("匿名代码块");
        }
        //只执行一次
        static {
            System.out.println("静态代码块");
        }
        public static void main(String[] args) {
            Student student = new Student();
            System.out.println("==============");
            Student student1 =new Student();
        }
    }
    /*
    执行结果如下:
    
    静态代码块
    匿名代码块
    构造方法
    ==============
    匿名代码块
    构造方法
    */
    
  • 类型转化:

    • 子类转换为父类,向上转型,可能会丢失方法
    • 父类转换为子类,向下转型,需要强制转换

6、抽象类和接口

一、抽象类

  • 定义抽象类:使用abstract关键字修饰的类,为抽象类。
  • 定义抽象方法:使用abstract关键字修饰的方法,为抽象方法。
  • 特点
    • 不能实例化。
    • 抽象类中可以写普通方法,抽象方法只能出现再抽象类中。
    • 抽象类的所有抽象方法,其子类都必须通过重写方法实现,除非其子类也是抽象类。

二、接口

  • 定义接口:使用intertface关键字修饰,为接口
  • 接口的特点:
    • 接口中所有定义方法都是抽象的,默认用修饰符“public abstract”修饰的,是可以缺省的。
    • 接口中所有定义的属性都是默认用修饰符“public static final”修饰的,是可以缺省的。
    • 接口不能被实例化,接口中没有构造函数,想要使用接口,需要用类去实现
  • 如何使用接口:
    • 通过类使用关键字implement去实现。
    • 其实现的类必须重写接口中的所有方法
  • 接口的作用:
    • 起约束作用,定义一些方法,可以有不同的实现
    • 可以起到多继承的效果

7、内部类

一、内部类

  • 成员内部类

    package com.oop.demo10;
    //Inner1为成员内部类
    //Inner2为内部类
    //一个java类中可以定义多个class类,但是只能有一个public class
    public class Test {
        public class Inner1{
            
        }
    }
    class Inner2{
        
    }
    
  • 静态内部类

    package com.oop.demo10;
    //Inner1为静态内部类
    //静态内部类不能访问外部类的非静态属性,因为静态内部类和外部类一起被加载,此时的非静态属性还没被定义。
    public class Test {
        public staic class Inner1{
            
        }
    }
    
  • 局部内部类

    package com.oop.demo10;
    //Inner1为局部内部类
    //局部内部类存在于方法中,且不能用public static 修饰
    public class Test {
        public void run(){
            class Inner1{
    
           }
        }
    }
    
  • 匿名内部类

    package com.oop.demo10;
    //user、userservice为匿名内部类
    //匿名内部类主要用于实现接口和抽象类,由于不能实例化,所有可以采用匿名内部类的方式。
    public class Test {
        public static void main(String[] args) {
           User user = new User(){
                @Override
                public void name() {
                    System.out.println("name");
                }
            };
           Userservice userservice = new Userservice(){
                @Override
                public void hello() {
                    System.out.println("hello");
                }
            };
            user.name();
            userservice.hello();
        }
    }
    
    abstract class User{
        public abstract void name();
    }
    
    interface Userservice{
       void hello();
    }
    
posted @ 2021-11-02 21:46  小超and车儿  阅读(108)  评论(0)    收藏  举报