面向对象(一)

面向对象

  • 相关概念

    面向过程编程与面向对象编程

    如何解决吃饭问题?

    面向过程:

1. 核心思想:自顶向下逐步求精
2. 自己做饭采购食材、原材料、调料,控火,控油,各种复杂步骤,不同的菜品还要有不同的步骤
3. 缺点:不易维护、不易复用、不易扩展、不易构造复杂程序。  (嵌入式、单片机)

​ 面向对象:

1. 点外卖找到能解决吃饭问题的对象即可,不需要关心内部如何实现。
2. 优点:易维护、易复用、易扩展、易构造复杂程序,是对于面向过程编程的一种升级

一、面向对象

  • Object Oriented Programming
  • 核心思想:以对象为单位,将解决客观世界问题的思想应用到编程领域中。

二、对象(Object)

(一)什么是对象?

- 概念:
由于程序需要帮助人类解决现实世界存在的问题,所以必须在程序中模拟出客观存在的事物,而对象就是对客观存在的事物一种统称。
简而言之:一切客观存在的事物都是对象。

(二)对象的组成部分

  • 客观世界存在的事物复杂多样,千奇百怪,但无论是什么对象都可以拆分成两个组成部分。

    1. 对象的属性,表示对象有什么,决定了对象的特征。
    2. 对象的方法,表示对象能做什么,决定了对象的行为。
    

    例:手机对象与洗衣机对象

    程序中的对象
    对象的属性使用变量表示
    对象的方法使用函数表示

    (三)对象与对象之间的关系(了解)

  1. 继承:还原客观世界的is a 关系; 例:步枪 is a 枪,步枪是一种枪
  2. 依赖:还原客观世界的 use a 关系; 例:枪 use a 倍镜,枪使用一个倍镜(弱关系)
  3. 关联:还原客观世界的 has a 关系; 例:枪 has a 扳机,枪有一个扳机 1V1 (强关系)
  4. 聚合:还原客观世界的 has some 关系; 例:枪 has some 子弹,枪有一些子弹 1VN

注意:客观世界就是由多个对象组成,对象的属性也可能是一个对象

三、类 (Class)

(一)什么是类?

  • 概念
类是对象的模板,用来描述对象具备的属性和方法。
JVM通过类中的信息创建对象(类的实例)
类是从多个相同类型对象抽取出的共性和特征,保留所关注的部分。

例:模板与实例

(二)类的组成部分

1. 属性/成员变量/实例变量

定义位置:类以内,方法以外 作用范围:至少在本类中 例:学生类

class Student{
  //属性
  String name;  //姓名
  int age;      //年龄
  boolean sex;  //性别
  double score; //成绩

 } 
1. 方法/成员方法/实例方法

    定义位置:类以内,其他方法以外

语法:

修饰符 返回值类型 方法名(参数表) 抛出的异常{
  //方法体
}
    例:
class Student{
  //属性
  String name;  //姓名
  int age;    //年龄
  boolean sex;  //性别
  double score;  //成绩
    //方法
  //学习方法
  public void study(){
    System.out.println("学习使我快乐");
  }
  //打招呼方法
  public void sayHello(){
    System.out.println("你好,我叫"+name+",今年"+age+"岁");
  }
}
     

注意:主函数与Student类无关,不要把主函数写在Student类中,如果需要主函数,我们会将主函数写到另外一个类中。

四、创建对象与使用对象

(一)创建对象

  1. 语法:

    new 类名();
    

    例:

    //创建Student对象
    new Student();
    //创建Teacher对象
    new Teacher();
    

    注意:创建对象前,务必保证此对象所对应的模板(类)已存在。

  2. 为引用赋值

    在Java中每定义一个类,就多了一种自定义的数据类型,可以将对象保存在同类型引用中 例:

Student stu1 = new Student();//创建Student对象并为 stu1引用赋值
Student stu2 = new Student();//创建Student对象并为 stu2引用赋值
Teacher t1 = new Teacher();//创建Teacher对象并为 t1 引用赋值

  1. 对象是独立的

模板只有一个,通过模板可以创建多个对象,每个对象都拥有自己独立的内存空间 例:

(二)操作对象中的属性

  • 语法:

    访问属性:对象名.属性名
    为属性赋值:对象名.属性名 = 值;
    

    例:

    Student stu1 = new Student();
    stu1.name = "张三";//为stu1的name属性赋值
    stu1.age = 18;    //为stu1的age属性赋值  
    stu1.sex = false; //为stu1的sex属性赋值
    stu1.score = 59.5;//为stu1的score属性赋值
    
    System.out.println(stu1.name);//访问stu1的name属性
    System.out.println(stu1.age);//访问stu1的age属性
    System.out.println(stu1.sex);//访问stu1的sex属性
    System.out.println(stu1.score);//访问stu1的score属性
    
    
    Student stu2 = new Student();
    stu2.name = "李四";//为stu2的name属性赋值
    stu2.age = 20;    //为stu2的age属性赋值
    stu2.sex = true;  //为stu2的sex属性赋值
    stu2.score = 60D; //为stu2的score属性赋值
    
    System.out.println(stu2.name);//访问stu2的name属性
    System.out.println(stu2.age);//访问stu2的age属性
    System.out.println(stu2.sex);//访问stu2的sex属性
    System.out.println(stu2.score);//访问stu2的score属性
    

    注意:数据类型必须兼容

  • 在内存中的体现:

  • 直接在类中为属性赋值称为初始化属性,此举会覆盖(替换)默认值。

    例:

class Student{
  //属性
  String name = "张三";  //姓名
  int age = 18;     //年龄
  boolean sex;     //性别
  double score;     //成绩
}

每次创建对象时name与age属性都会赋值为张三,18,其余属性为默认值:

(三)调用对象中的方法

  • 语法:

     对象名.方法名( 实参 );
    

    例:创建Student对象,调用study方法与sayHello方法

    Student stu1 = new Student();
    stu1.name = "张三";
    stu1.age = 18;
    stu1.score = 59.5;
    stu1.sex = false;
    
    stu1.study();//调用stu1中的study方法
    stu1.sayHello();//调用stu1中的sayHello方法
    

    执行流程:

  • 调用复杂方法(传入参数,接收返回值)

例:

//学生类
class Student{
    //属性
    String name;  //姓名
    int age;    //年龄
    boolean sex;  //性别
    double score;  //成绩
    double pinMoney;//[新增]零用钱
    //方法
    //学习方法
    public void study(){....}
    //打招呼方法
    public void sayHello(){....}
    //[新增]购物方法
    public double shopping(String goods,double price){
        System.out.println("购买:"+goods);
        System.out.println("需支付:"+price);
        pinMoney -= price;//减少零用钱
        System.out.println("零用钱剩余:"+pinMoney);
        return price;//支付费用
    }

}
//测试类
public class TestObjectOriented {
    public static void main(String[] args) {
        Student stu1 = new Student();
        stu1.name = "张三";
        stu1.age = 18;
        stu1.score = 59.5;
        stu1.sex = false;
        stu1.pinMoney = 100D;

        double money = stu1.shopping("打气筒",15.0);
        System.out.println("商店收入:" + money);
    }
}

执行流程:

五、局部变量与成员变量的区别

局部变量 成员变量
定义位置 方法中 类的内部,方法的外部
默认值 有(与数组元素默认值相同)
作用范围 从定义行开始到所在代码框结束 至少在本类中
命名冲突 重合作用范围内不允许重名 可与局部变量重名,局部变量优先

六、方法的重载(Overload)

  • 作用:在一个类中可以定义多个同名的方法,屏蔽使用时的差异,更加方便。

    例:

//计算器类
class Calculator{    
  public void sum1(int ,int){...}//求和方法1
  public void sum2(double , double){...}//求和方法2
  public void sum3(int,double){...}//求和方法3
  public void sum4(double,int){...}//求和方法4
}
 

对于使用者而言非常不方便,虽然方法的作用一样,但是由于要处理的数据类型不同进而需要记住各种方法名与其对应的参数。

  • 方法重载的语法:

    方法名相同,参数个数、类型、顺序不同,返回值类型、修饰符无要求
    

    例:

    class MyClass{
      public void m1(){...}
      public void m1(int a){...}
      public void m1(String str){...}
      //public void m1(String abc){  }  Error  形参名不同 不算重载
      public boolean m1(double a){ return false;}
        public void m1(int a , String b){...}
        public void m1(String a, int b){...}
    }
    

    注意: 编译器会根据实参的类型、顺序、个数自动匹配对应的方法。

七、构造方法

  • 概念:构造方法也称为构造器,是一种特殊的方法,每次创建对象会自动调用。
  • 特点:
1. 每次创建对象会自动调用
2. 如果没有手动定义构造方法,编译器默认提供无参构造。
3. 如果手动定义了构造方法,编译器则不再提供默认无参构造。
4. 构造方法支持重载,可以定义多个
  • 语法:
1. 构造方法的方法名与类名必须一致
2. 构造方法没有返回值类型
3. 构造方法在创建对象时会自动调用,不能手动调用

例:


构造方法支持重载,可以定义多个

例:

class MyClass{
    MyClass( ){...}
    MyClass(int a){...}
    MyClass(double b){...}
}
  • 作用:使用构造方法为属性赋值 步骤:
1. 在构造方法中添加与属性类型个数相同的参数
2. 使用形参为属性赋值
3. 创建对象时传入实参,减少赋值代码
  
class Student{  
   String   name;   
   int   age;    
   boolean   sex;  
   double   score;
   double   pinMoney;

   //无参构造方法
   Student(   ){...}

   //有参构造方法
   Student(String a, int b, boolean c , double d , double e){
       //使用参数为属性赋值
       name = a;
       age = b;
       sex = c;
       score = d;
       pinMoney = e;
   }     
}
//测试类
class TestStudent{
  public static void main(String[] args) {
      //创建对象时使用有参构造方法,传入实参
        Student stu1 = new Student("张三",18,false,59.5,100.0);
  }
}

八、对象的创建过程

  • 对象的创建过程与动作:
  1. 分配空间,为对象的属性分配默认值
  2. 初始化属性,初始化对象的属性
  3. 调用构造方法,使用构造方法可再次为属性赋值

九、数据传递规则 transmit

1. 基本类型传值,两者之间任何一方更改,不影响另一方。
2. 引用类型(对象、数组)传地址(形参和实参会指向同一对象),两者之间任何一方更改,影响另一方

课堂案例:

class Student{
    String name;
    int age;
    Student(String a , int b){
        name = a;
        age = b;
    }
}

class TestMyClass{
   public static void main(String[]args){
       int a = 10;
       changeVar( a );
       System.out.println( a );//10
       
       Student stu1 = new Student("杨冬冬" , 30);
       changeObj( stu1 );
       System.out.println( stu1.age );//40
   }
   public static void changeVar( int a ){
       a = 20;
   }
   public static void changeObj( Student stu1 ){
       stu1.age = 40;
   }
}

打印引用,可以获得对象所在内存地址,必须通过引用获取地址中存储的数据 在类中直接打印属性,代码都一样,程序怎么知道我打印的是哪个对象的属性?

十、this关键字

  • 含义:运行时由JVM自动创建的变量,表示当前对象引用 例:

(一)使用this.访问属性或方法

  • 语法:
访问属性:this.属性名;
访问方法:this.方法名(实参);
  • 例:
class MyClass{
    int a ;
    public void m1(){
        System.out.println(" m1( ) ");
    }

    public void method(){
        this.m1();//调用m1方法
        System.out.println( this.a );//访问a属性
    }
}
  • 可用于区分局部变量与实例变量[重点掌握]
class MyClass{
    int a ;

    public void method(int a){
        System.out.println( a );//打印局部变量 a
        System.out.println( this.a );//打印属性 a
    }
}
  • 优化构造方法[重点掌握]
class Student{
    //属性
    String name;  //姓名
    int age;    //年龄
    boolean sex;  //性别
    double score;  //成绩
    double pinMoney;//零用钱
    Student(){...}//无参构造
    Student(String name , int age, boolean sex , double score , double pinMoney){
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.score = score;
        this.pinMoney = pinMoney;
    }
}

(二)使用this( )调用本类其他构造方法

  • 语法:
必须在构造方法的第一行
this( );//调用本类无参构造
this( 实参 );//调用本类有参构造
  • 作用:提高构造方法的重用性

    例1:

class MyClass{
    int a;
    MyClass(){
        System.out.println("MyClass( )");
    }
    MyClass(int a){
        this();
        this.a = a;
        System.out.println("MyClass(int a)");
    }
}

例2:

class Account{
  String no;      //卡号
  String password;  //密码
  double balance;    //余额
  public Account(String no,String password){
    this.no = no;                                
    this.password = password;
  }
  public Account(String no,String password,double balance){
    //使用其他构造方法初始化属性
    this(no,password);//提高构造方法的重用性
    this.balance = balance;
  }
}

注意:this() 只能定义在构造方法的第一行

十一、拓展知识

(一)对象数组

- 将多个相同类型的对象存储在数组中,便于进行统一操作

例:将多个学生对象存储到学生数组中

//创建Student类型的数组,该数组有3块内存空间,可以存储3个学生对象,并不是一次性创建3个学生对象
Student[] stus = new Student[3];
//创建学生对象,将对象存储到数组中
stus[0] = new Student("wangyx",16,100.0);
stus[1] = new Student("yangdd",32,59.9);
stus[2] = new Student("zhangmj",18,99.0);

//统计平均分
//遍历数组获取每名学生的成绩并且求和
double sum = 0;//记录所有学生的总成绩
for(int i=0; i<stus.length; i++){
    //从数组中获取学生对象
    Student stu = stus[i];
    //获取属性,为变量score赋值
    double score = stu.score;
    //将score累加到sum变量中
    sum += score;
}

//计算平均分 用总成绩/人数
System.out.println("平均分为:"+ sum/stus.length );
posted @ 2022-09-28 20:59  小牛同志  阅读(109)  评论(0)    收藏  举报