面对对象

面对对象&面向对象

  • 面向过程思想:

    • 步骤清晰简单,第一步做什么,第二不做什么...
    • 面对过程适合处理一些较为简单的问题
  • 面向对象思想

    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要那些分类,然后对这些分类进行单独思考,最后,才对某个分类下的细节进行面向过程的思索。
    • 米娜想对象适合处理复杂的问题,适合处理需要多人写作的问题。
  • 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象思路来分析整体系统。但是,具体到微观操作,任然需要面向过程的思路去处理。

什么是面向对象

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

方法的加深

break与return的区别

  • break作用为跳出switch,结束循环
  • return作用为结束方法,返回一个结果,一个方法内return后代代码都不执行

实参与形参

  • 形参:参数定义的名字

  • 实参:参数被赋予的值

实参与形参的类型必须要一一对应

方法的调用

  • 静态方法

    加了static的方法,和类一起加载, 可以直接调用

  • 非静态方法

    类实例化之后才存在,需要实例化类 new

  • 例子:静态方法调用
//Student类
public class Student {
    public static void say(){
        System.out.println("有学生说话了");
    }
}

//调用静态方法
public class Demo01 {
    public static void main(String[] args) {
        //调用静态方法
        Student.say();
    }
}    
  • 例子:非静态方法调用
//Student类
public class Student {
    public void say(){
        System.out.println("有学生说话了");
    }
}
//调用Student类里的say方法
public class Demo01 {
    public static void main(String[] args) {
        Student student = new Student();//实例化类
        student.say();
    }
}    

值传递与引用传递

  • java都是值传递

this关键字

  • 意义:

    1. 代表当前对象
    2. this就是所在函数所属对象的引用,简单来说,哪个对象调用了this所在的函数,this就代表哪个对象
  • 应用:

    1. this可指向当前的类
    2. 当成员变量和局部变量重名,可以用关键字this区分,

    ​ 如:

    class Person
    {
    	private String name;
    	private int age;
    	Person(String name)
    	{
    		//成员变量和局部变量重名,可以用关键字this区分
    		this.name = name;
    	}
    	public void speak()
    	{
            //输出时,会默认为成员增加this关键字,用来代表具体对象的数据
    		System.out.println(this.name+":"+this.age);
    	} 
    }
    
    
    1. this关键字也可以用于在构造函数中调用其他构造函数。*但是,只能定义在构造函数的第一行,因为初始化动作要先执行。*

      如:

      class Person
      {
      	private String name;
      	private int age;
      	Person()
      	{
      		name = "baby";
      		age = 1;
      		System.out.println("Person run");
      	}
      	Person(String name)
      	{
      		//成员变量和局部变量重名,可以用关键字this区分
      		this.name = name;
      	}
      	Person(String name,int age)
      	{
      		//调用其他构造函数时,只能定义在构造函数的第一行,因为初始化动作要先执行
      		this();
      		this.name = name;
      		this.age = age;
      	}
      	public void speak()
      	{
      		System.out.println(this.name+":"+this.age);
      	}
       
      }
       
       
      class ThisDemo 
      {
      	public static void main(String[] args) 
      	{
      		Person p = new Person("老王",10);
      		p.speak();
      	}
      }
      

类与对象的关系

  • 类是一种抽象的数据类型(可看成一个模板),它是对某一类事物整体描述、定义,但是并不能代表某一个具体的事物。
    • 如:动物、之物、手机、电脑......
    • Person类、Pet类、Car类等,这些都是用来描述/定义某一类具体的事物应该具备的特点和行动
  • 对象是抽象概念的具体实例

    • 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例。
    • 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象概念。
  • 一个项目应该只存在一个main方法

创建于初始化对象

  • 使用new关键字创建对象
  • 使用new关键字创建的时候,出了分配内存空间之外,还会给创建好的对象进行默认的初始化 以及对类中构造器的调用
  • 累的构造器也称为构造方法,是在进行创建对象的时候必须要调用的,并且构造器有以下两个特点:
    1. 必须和类的名字相同
    2. 必须没有返回类型,也不能写void
  • 构造器必须要掌握

  • 例子:

    //学生类
    public class Student {
        //属性 :字段
        String name;//null
        int age;//0
        //方法
        public void student(){
            System.out.println("这个学生是:"+this.name+",年龄是:"+this.age+"岁");
        }
    }
    
    public class Application {
        public static void main(String[] args) {
            //类:抽象的,需要实例化
            //类实例化后返回回一个自己的对象!!
            //student对象就是一个Student类的具体实例!
    
            Student Wangxiaoming = new Student();
            Wangxiaoming.name = "王小明/李小狼";
            Wangxiaoming.age = 10;
            Wangxiaoming.student();//调用student方法
        }
    }
    

构造器

  • 构造器:

    • 和类名相同
    • 没有返回值
  • 作用:

    1. 使用new关键字必须要有构造器,它的本质是调用构造器
    2. 初始化值
  • 快捷键 alt + insert :自动生成构造器

  • 实例:

    • 无参构造:

      public class Person {
          //一个类即使是什么也不写,它都会存在一个方法
      
          //显示定义构造器
          String name;
      
          //实例化初始值
          public Person(){//这里括号内没有参数
              this.name = "王小明";
          }
      }
      
      
      public class Application {
          //一个项目只存在一个main方法
          public static void main(String[] args) {
              //用 new 实例化了一个对象
              Person person = new Person();
              //到实例化构造器结束
              System.out.println(person.name);
          }
      }
      
      
    • 有参构造:

      一旦定义了有参构造,无参构造就必须显示定义,否则无效(定义了有参构造,无参构造就默认为空了)

      public class Person {
          //一个类即使是什么也不写,它都会存在一个方法
      
          //显示定义构造器
          String name;
      
          //实例化初始值
          //午餐构造
          public Person(){
              this.name = "王小明";
          }
      
          //有参构造,一旦定义了有参构造,无参构造就必须显示定义,否则无效(定义了有参构造,无参构造就默认为空了)
          public Person(String name ){
              this.name = name;
          }
      }
      
      
      public class Application {
          //一个项目只存在一个main方法
          public static void main(String[] args) {
              //用 new 实例化了一个对象
              Person person = new Person("木之本樱");//定义有参构造后无参构造默认无值,所以要赋值
              //到实例化构造器结束
              System.out.println(person.name);
          }
      }
      

封装

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

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

  • 例子:

public class Student {
    //属性名私有
    private String name;//名字
    private int id;//学号
    private  char sex;//性别

    //提供一些可以操作这个属性的方法
    //提供一些public的get、set方法

    //get 获得这个数据
    public String getName(){
        return this.name;
    }
    //set 给这个数据设置值
    public  void setName(String name){
        this.name = name;
    }

}


public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("王小明");
        System.out.println(s1.getName());

        //alt + insert 可自动生成get、set方法
    }
}


  • 封装作用:
    1. 提高程序安全性,保护数据
    2. 隐藏代码的实现细节
    3. 统一接口
    4. 系统可维护性增加

继承

  • 继承的本质是对某一批类的抽象,从而实现对现世界更好的建模
  • extands 的意思是“拓展”。子类是父类的拓展。
  • java中了只有单继承,没有多继承
  • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有以来、组合、聚合等
  • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键词extends来表示。
  • 子类和父类之间,从意义上讲应该具有“ is a“的关系
  • 私有的东西无法被继承

super

  • 掉膘父类对象的引用

  • 调用父类的构造器(构造方法)

  • super 必须写在自构造器的第一行

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

    super 与 this的区别

    1. 代表的对象不同:

      this:本身调用这个对象

      super:代表父类对象的应用

    2. 前提不同:

      this:没有继承也可以用

      super:只能在继承条件下才可以使用

    3. 构造方法不同:

      this(); 本类的构造

      super(); 父类的构造

方法的重写

  • 重写都是方法的重写,和属性无关

  • 需要有继承关系,子类重写父类

  • 参数列表必须相同

  • 方法名必须相同

  • 修饰符:范围靠扩大但是不能缩小

    • public > protected > Default > private
  • 抛出异常:范围:可以被缩小,但不能扩大

  • 为什么需要重写

    1. 父类的功能,子类不一定需要或者不一定满足
    2. alt + insert :override ,可快捷生成

多态

  • 同一方法可以根据发送帝乡的不同采用多种不同的行为方式
  • 一个对象的实际类型是确定的,但可以指向对象的引用有很多
  • 多态存在的条件:

    • 有继承关系
    • 子类重写父类的方法
    • 父类引用指向子类对象
  • 注意:多态是方法的多态,属性没有多态性

  • 注意事项

    1. 多态是方法的多态,属性是没有多态性的
    2. 父类盒子类,有联系 (类型转换异常提示:classCastException)
    3. 存在条件:继承关系,方法需要重写,父类的引用指向子类对象
  • instanceof 关键词(类型转换)

    用于判断A、B之间是否有父子关系,有着可通过编译

    System.out.println(A instanceof B);
    
    
  • 若要父类调用子类独有而自身没有的方法,需要强制转换(高转低)

如:

Person person = new Student();
Student student = (Student) person;//转换

  • 例子:

    public class Person {
        public void name(){
            System.out.println("this is a father");
        }
    }
    
    public class Student extends Person{
        @Override// alt + insert自动生成的重写
        public void name() {
    
            System.out.println("this is a son ");
        }
    
        public void run(){
            System.out.println("正在跑步");
        }
    }
    
    
    public class Application {
        public static void main(String[] args) {
            //一个对象的实际类型是确定的
            // 如 new Student(); new Person();
    
            //但是可以指向的引用类型就不确定了
            //父类的引用指向子类
            Person s1 = new Student();
            Student s2 = new Student();
            //但是父类无法调用子类独有的方法
    
            s1.name();
            s2.name();//子类重写了父类的方法,执行子类的方法
    
            System.out.println(s1 instanceof Student);// 转换类型,判断是否存在父子关系
    
            //若父类调用子类有方法而自身没有的方法,需要进行强制转换
            Student student = (Student) s1;//将Persond的对象强制转换为Student类型
            student.run();
            //或者直接写成 (Student)s1.run();
            //如果是Person person = student;(子类转换为父类,低转高)。可能会丢失一些方法
        }
    }
    

static关键字详解

  • 静态方法可以调用静态方法,但不能调用非静态方法

  • static只执行一次

抽象

  • 在一个类的 class 前面使用 abstract 关键字,这个类就变成抽象类了

  • 抽象类的所有方法必须要由子类实现,继承了他的子类都必须实现他的方法,除非他的子类也是抽象类否则立马报错(子类重写方法)

  • 注意:

    1. extends是单继承,但是接口可以多继承

    2. 不能去new一个抽象类,只能通过子类去实现它:约束!!!

    3. 抽象类中可以写普通方法(抽象的抽象)

    4. 抽象方法必须在抽象类中

  • 抽象类的意义:

    把公用的部分抽象出来,要用重写方法就好,节省开发流程

接口

区别:

  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 只有规范!自己无法写方法,这是专职约束。约束和实现分离,面向接口编程

什么是接口

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

  • 接口的本质是契约,就像法律一般,制定好后就必须遵守

  • 设计模式的精髓,是对对象的抽象,最能体现这一点的就是接口。另外,设计模式所研究的,实际上就是如何合理的去抽象

  • interface代表接口

作用

  1. 约束
  2. 定义一些方法,让人实现
  3. 默认的方法是 public abstract
  4. 默认的常量都是 public static final
  5. 接口不能被实例化,接口中没有构造方法
  6. implements关键字可以实现多个接口

内部类

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

如:

public class Outer {
    private int id=233;
    public void out(){
        System.out.println("这是一个外部类的方法");
    }
    public class Inner{
        public void in(){
            System.out.println("这是一个内部类方法");
        }
        public void getID(){//获得外部类的私有属性
            System.out.println(id);
        }
    }
}


public class Application {
    public static void main(String[] args) {

        Outer outer = new Outer();
        //通过这个外部类来实例化内部类
        Outer.Inner inner = outer.new Inner();
        inner.getID();
    }
}

  • 静态内部类无法直接访问非静态属性

  • 注意,一个java类中可以有多个class类,但只能有一个public class

    如:

    public class Outer{
    
    }
    
    class Inner{
    
    }
    
上一篇:设计模式 - 抽象工厂模式


下一篇:面对对象设计六大原则