05-面向对象基础

在Java当中,面向对象是Java的核心。

面向对象的概念

  • 面向对象是什么
    • 面向对象是一种编程思想,是相对于C语言中面向过程而言。
      • 先有面向过程,再有面向对象
      • Java为什么会诞生? C语言 存在一些无法解决的 应用程序开发问题
      • 编程思想不同: 面向过程以实现功能的函数开发为主,而面向对象要首先抽象出类、属性及其方法,然后通过实例化类、执行方法来完成功能。
    • 【面向过程】强调的是功能行为;【面向对象】强调的是具备功能的对象。
      • 在解决复制问题时,面向对象有更大的优越性

eg:小明喜欢喝奶茶。

面向过程:需要小明自己动手做(去某宝买芋圆、奶精、调味料、茶饼)==> 1小时

面向对象:去奈雪の茶买一杯多肉葡萄芝士冷饮来喝。 ===> 对象:奈雪的茶 功能:制作奶茶

  • 面向对象的程序开发原则:
    • 如果有对象就用对象,对我们提供服务;
    • 如果没有对象,则创建对象,然后使用对象、指挥对象做事情。

面向对象的开发语言 如Java 其实就是 创建对象、使用对象、指挥对象做事情。

  • 面向对象思想特点:
    • 更符合我们思想习惯的思想;-- 懒人思想
    • 将复杂的事情简单化;--- 对于 对象来说,其实是一件复杂的过程
    • 将我们从执行者过度到指挥者。-- 角色互换
  • 怎么建立面向对象的思维方式?
先整体(人),再局部(张三)
先抽象,  再具体
能做什么,再怎么做。

面向对象中两个重要的概念——类和对象。

面向对象概念—类

  • 现实世界中的类:
    • 类--> 分类、类别
    • 为了更好的认识世界,通过分类,可以区分不同事物的种类。同一类中事物总具有相同的共性,再将共同的特性和行为定义成 【实体对象】。

eg: 类:

  • 动物 ——> 实体对象:猫🐱,狗🐕,蛇🐍 ==> 有生命,会动、有思想
  • 水果 ——> 实体对象:苹果🍎,香蕉🍌 ===> 鲜甜、 好吃
  • 在Java中,为了更好的描述现实世界,同样也对类进行定义:
    • 类是描述对象的“基本原型”,它定义一类对象所能拥有的数据和可完成的操作。
      • 类是由一组具有相似的(相同的)属性(数据)和行为(可完成的操作)组成的。
      • 类是由属性 和 行为 组成。

描述人类:姓名、年龄、性别、身高、。。。 =>属性

  • 能做什么 如果是学生学习 警察抓小偷 战士 保家卫国 => 行为(功能)
  • 在面向对象的程序设计中,类是程序的基本单元。
  • 写一个程序就是写一个类
  • 程序中的对象是类的一个实例。
  • 对象是类的具体体现。类是将对象抽象化,是对象的模板;
  • 而对象呢就是类的实例化(具体化),真是存在的个体。

面向对象概念—对象

对象两种定义:

  1. 现实中,是真实存在的个体。
  2. Java程序中,是由一组变量和相关方法构成的。
  • 其中,变量表示对象的属性(状态),方法表示对象所具有的行为。
描述学生: 根据  人类: 属性(姓名、年龄、性别、身高)    行为 ( do())


学生  属性(变量):姓名  张三   年龄18  性别 男   身高180cm   -- 名词


     行为(方法):学习       -- 动词


警察  属性:姓名  李四   年龄28  性别 男  身高180cm


	  行为:抓小偷

我们可以将生活中的对象抽象出来,映射到程序。而对象在程序中是通过一种抽象数据类型来描述的,这种抽象数据类型称为类(class)。

例子:定义一辆小红车

在程序中,描述对象的方法:通过该对象拥有的属性和行为

属性:该事物的描述数据信息(事物身上的名词)

行为:该事物能够做什么(事物身上的动词)

车的属性:颜色、门、速度

车的功能(行为):刹车、加速、减速

Class Car
{
    int colorNumber;  
    int doorNumber;
    int speed;
   
    void brake() { … }
    void speedUp() {…}
    void slowDown() { …  }
}

面向对象的思维:

先整体(车),局部(红色的车)

先抽象(属性颜色),再具体(红色的)

能做什么(刹车),再怎么做(急刹车、轻刹车)

类和对象的关系

  1. 类定义了一种新的数据类型(类类型),可以用新类型来创建该类型的对象。
    • 类类型也是数据类型中引用数据类型的一种,自定义的类,也可以用来创建变量和创建对象。
  2. 类是对象的模板,对象是类的一个实例。
    • 类是抽象的,而对象是具体的一个个体。

类的组成

变量:对象的属性(状态)
方法:对象的功能单元——对象可以做什么。
消息:对象通过相互间传递消息来相互作用和通信。 对象A ——> 对象B   
		比如 学生捡到5毛 交给警察叔叔  --> 对象C  失主
		
对类的应用
1)接受消息的对象  -- 对象是谁
2)接收对象要采取的方法 -- 对象要做什么
3)方法需要的参数  -- 对象 要怎么取做

类的定义方式

  • 由关键字class定义,类体中包含变量的定义和初始化、方法的定义及方法体。
    • 变量——属性(该事物的数据信息/事物的名词):
    • 方法——行为(该事物能做什么/事物的动词):
[权限访问][类的修饰符] class 类名 { 
	//变量的定义及初始化 
	type 变量名 [=value];
    
	//方法的定义及方法体
	[修饰符] 返回数据类型 方法名 () { ---> void表示没有返回值
		方法体;
	}
}

案例1:定义一个学生类

类的描述:属性和行为(功能)

属性:学生的年龄、学生的性别、学生的姓名

行为(功能):学习、考试、吃饭。。。

public class Student {
	//变量:描述学生的属性
	int age;
	char sex;
	String name;
	
	//方法:描述学生具备的行为
	//语法格式:[修饰符] 返回值 方法名(参数(可选)){ 方法体 }
	//返回值:void 表示方法没有返回值
	public void study() {
		System.out.println("student中的study方法……");
	}
	
	public void test() {
		System.out.println("学生会考试");
	}
	//有返回值的方法,方法体中要有return,返回数据的数据类型必须和返回值数据类型一致
	//例子,获取学生的姓名
	public String getName() {
		return name;
	}
}

案例2:学生类的简单使用

写了一个程序(类),一般在主方法下进行自测。

对类的使用:怎么创建对象,怎么使用对象的属性和对象的方法,做演示。

//一个程序要运行,需要一个入口。--main方法作为程序运行的主入口
	public static void main(String[] args) {
		//创建对象:类名 对象名 = new 类名();
		Student st01 = new Student();
		System.out.println(st01);//包名+类名和内存自动分配的地址
		//访问对象的属性和方法?
		//属性:对象名.变量名
		System.out.println("name="+st01.name);
		System.out.println("age="+st01.age);
		System.out.println("sex="+st01.sex);
		//对对象的属性进行操作
		st01.sex ='男';
		System.out.println("改变对象的sex="+st01.sex);
		//方法:对象名.方法名()
		st01.study();
		st01.test();
		String myName = st01.getName();//String myName = "张三";
		System.out.println("myName="+myName);
	}

类的组成--变量(按作用域)

1.全局变量

全局变量(成员变量):在类体中定义,作用域:整个类或者外部类可以被使用。

  • 静态变量(类变量、类成员变量、静态成员变量):由static关键字修饰,可被所有该类的对象共享
  • 实例变量:无static修饰,只能被对象独享。

案例3:全局变量

public class Person {
//全局变量:类体中定义
    String name ;
    int age;
    static String city;
    public static void main(String[] args) {
    // 创建Person对象,用new
        Person pn_01 = new Person();
    //静态方法中,不允许直接访问实例变量,实例变量需要通过实例化一个对象方法。可以直接访问静态变量。
    // 静态变量的获取方式:
        System.out.println("类名.静态变量:" + Person.city);
        System.out.println("对象名.静态变量:" + pn_01.city);// 静态变量,也可以对象名.
        System.out.println("在本类中,可以直接用静态变量名:" + city);
    // 实例变量的获取方式:
        System.out.println("对象名.实例变量age:" + pn_01.age);
        System.out.println("pn_01.age="+pn_01.name);
    }

案例4:静态变量与实例变量的区别

package day05_object;
/**
 * 全局变量:静态变量(类变量) + 实例变量的区别
 * @author wyn
 *
 */
public class Student {
	//属性 (描述事物的数据信息)-->  变量(用来存储数据)
	//全局变量(成员变量)
	String name = "张三";  //实例变量
	int age;
	char sex ='男';
//	String school ="华大";
	static String country ="中国";   //静态变量:由static修饰
	static String school = "华大";
	final int MAX_VALUE = 10;  //定义常量
	
	public static void main(String[] args) {    //测试
		//方法体
		//类的简单使用:  创建对象, 通过对象名 去调用 对象的属性 或者方法:
		// 语法:类类型  对象名  =  new 类名();
		Student s1 = new Student(); //创建对象
		//访问学生s1的姓名:  对象名.name
		System.out.println("s1学生的名字:"+ s1.name);
		//访问学生s1的学习的方法:  对象名.study()  
		s1.study();
		System.out.println("--------实例变量的访问方式--------");
		//实例变量的访问方式:  只能是  对象名.实例变量,  并且 实例变量 不能直接在静态方法中使用
		System.out.println("对象名.实例变量:"+  s1.name +",年龄"+s1.age +"性别"+s1.sex);//
//		System.out.println("类名.实例变量:"+  Student.name );//  
//		System.out.println("访问实例变量,如果没有对象名:" +name + age + sex);   // 实例变量 不能在静态方法中使用
		System.out.println("--------静态变量的访问方式--------");
		//静态变量的访问方式:可以通过【对象名或者  类名】.静态变量,  静态变量 可以在 本类中 直接调用。
		System.out.println("访问静态变量,用对象名.静态变量: 学生来自" + s1.country);//The static field Student.country should be accessed in a static way
		System.out.println("访问静态变量,用  类名.静态变量: 学生来自 "+ Student.country);  //推荐:类名.静态变量,是专门用来调用静态变量的方式
		System.out.println("访问静态变量,直接用变量名:"+  country);
		System.out.println("------对象直接的判断相等问题:-------");
		System.out.println("s1学生的名字:"+ s1.name);
		System.out.println("s1学生来自:"+ Student.country);
		Student s2 = new Student();
		System.out.println("s2学生的名字"+s2.name);
		System.out.println("s2学生来自:"+ Student.country);
		System.out.println("疑惑  s1 和 s2 是不是同一个人:" + (s1 == s2) );   //字符串"疑惑  s1 和 s2 是不是同一个人" + s1      与     Student类s2    进行 ==比较
		System.out.println("s1="+s1);  //cn.goktech.Student@7852e922    包名.类名 @ 
		System.out.println("s2="+s2);  //cn.goktech.Student@4e25154f
//		Student s2 = new Student();
		System.out.println("--------------实例变量 和 静态变量的修改权限:--------------");
		s1.age =18;
		s2.name = "李四";   //实例变量
		s2.age =20;       //实例变量
		System.out.println("s1学生的名字:"+ s1.name+"年龄是"+s1.age);
		System.out.println("s1学生来自:"+ Student.country + ",并且就读于:"+s1.school);
		System.out.println("s2学生的名字:"+s2.name+"年龄是"+s2.age);
		System.out.println("s2学生来自:"+ Student.country + ",并且就读于:"+s2.school);
		
		System.out.println( "---此时,s1同学转学,转去 集美,   s2同学并没转学---");
		s1.school ="集美";  //Student.school ="集美"
		
		System.out.println("s1学生"+s1.name +"来自:"+ Student.country + ",并且就读于:"+s1.school +"--"+ Student.school);   //集美
		System.out.println("--s1转学后,那么s2同学在哪里读书?---");
		System.out.println("s2学生来自:"+ Student.country + ",并且就读于:"+s2.school+"---"+Student.school);  //s2同学没有转学, 和s1同学很好 


		//总结:全局变量: 类体中定义,如果没有给定初始值的时候,系统会给帮忙给定 相应数据类型默认值。
//		成员变量 不能有相同标识符
//		实例变量访问、修改权限: 通过【对象】去调用实例变量, 修改:某个对象修改实例变量,只会修改自己的属性,不会去影响其他对象。
//		静态变量访问及修改权限:通过【类或者对象】去调用静态变量;
		//变量修改:静态变量,如果某个对象对它进行修改,会导致其他对象获取静态变量时, 拿到的值时 更改后的 值
		
	}

总结:静态变量与实例变量的区别

  • 访问:

静态变量——通过【类或者对象】访问静态变量。

实例变量——只能通过【对象】访问实例变量。

调用静态变量类名.静态变量的方式调用,在本类中可以省略。

  • 变量修改:

实例变量——只能被一个类对象独享,修改对象自己的实例变量不影响其他对象。

静态变量(类成员变量)——被多个类对象共享。当某个对象修改静态变量时,后面访问该静态变量,则是修改后的值。

  • 生存周期 (下一章详细讲):实例变量与类对象生存周期共存亡。类成员变量与类共存亡。

2.局部变量

局部变量:在代码段中定义(方法体、if、for等),只能在当前代码中使用或者该代码段的子代码段中可见

  • 方法局部变量(在方法内定义)
  • 形参(函数形参)
  • 代码块局部变量(在代码块内定义;下一章详细讲)
class Person01{
 //2.1 方法中变量
    //方法的定义语法格式: 修饰符 返回类型 方法名(参数1..) {方法体}
	public void sum() {
		int x=5,y;
		y=10;
		System.out.println("方法局部变量:"+name+"会计算x+y="+(x+y));
	}
//2.2形参变量( 方法(形参) )
	public void sum(int a,int b) {  
		int c =5;
		System.out.println("形参变量:"+name+"会计算a+b+c=" +(a+b+c));
	}
//3.3代码块变量 {} :代码块中的代码怎么调用,什么时候会被调用
	{
		int m =5;
		age=18;
   	 	System.out.println("****这个是谁调用:"+name+",代码块变量m="+m);
	}
}
  • 注意:
    • 1)局部变量使用前,必须进行显示初始化或者赋值。
    • 2)(下一章详细讲)当类实例化new一个对象的时候,代码块{}会首先被调用,同时也是最后一次被调用。

3.两者之间的区别

全局变量和局部变量之间的区别:作用域不同、初始值不同、声明上不同、优先级不同

  1. 全局变量(成员变量)定义时未设置初始值,则系统会根据成员变量的类型自动分配初始值。局部变量在定义时必须显式初始化或赋值,才能够使用局部变量。
  2. 全局变量:在一个类中不允许声明同名变量;
  3. 局部变量:在一个方法中不允许声明同名变量,但是可以和全局变量名相同,而且在局部变量作用范围内的优先级高。
  4. ——如果要在局部变量的作用域范围内访问该全局变量(成员变量)则必须要用this关键字
  5. 使用局部变量比使用全局变量更安全。
Class person {
	int age=20;
	String name;
	
	public void myAge(){
		int age = 18;
         system.out.println("我的年龄是"+age);//18
         system.out.println("我的真实年龄是"+this.age);//20
	}
}

this关键字

this指向自己的引用,即当前方法所在的对象
案例:this简单应用

Class person {
	int age=20;
	String name;
	
	public void setAge(int age){
		this.age = age;
         system.out.println("形参age"+age);//18
         system.out.println("成员变量age是"+this.age);//20
	}
    public int getAge(){
        return this.age;//这边的this 可以省略。
    }
}

类的组成--方法

方法的定义

[访问权限][方法修饰符] 返回类型  方法名(参数1,参数2,…) [throws exceptionList] {
	方法体
}

方法分类

1.按返回值

1)有返回值:任意合法的数据类型;
方法有返回值,方法体必须有return,且return中的数据类型,必须和返回值数据类型一致。

2)无返回值:void;


2.按参数

1)无参:方法名后的括号无参数;

2)有参:方法名后的括号有参数,该参数叫做 形参。

形参与实参的定义
- 形参:方法名(形参)
- 实参:调用方法时,赋予的值-->可以是实际的数值或变量

3.按功能

  • 实例方法 -- 无static
  • 静态方法(类方法) -- 有static

构造方法(构造函数、构造器):

- 构造函数用来初始化该类的一个新对象,在系统创建对象时自动执行。

- 一个类若没有定义构造函数,系统默认定义无参的空实现的构造函数。


案例:方法按功能可分为三类

public class TestFunction {
	int age;
	String name;
	char sex;


	//方法按功能分,有三种
	//1.实例方法 -- 无static
	public void eat() {
		System.out.println("这是一个实例方法eat()");
	}
	//2.静态方法(类方法) -- 有static
	public static void sleep() {
		System.out.println("这是一个静态方法sleep()");
	}
	//3.构造方法(构造函数\构造器): 在创建new对象的时候,调用
	//语法格式:修饰符 类名名(可选参数){ 无return..}
	//构造函数用来初始化该类的一个新对象,在系统创建对象时自动执行.
	//一个类若没有定义任何构造函数,系统默认定义无参的空实现的构造函数;
	
	/*public TestFunction() {
		System.out.println("这是一个无参构造函数");
		System.out.println("age="+age);
	}*/
	public TestFunction(int age) {
		System.out.println("这是一个有参构造函数..");
		this.age = age;
	}
	public TestFunction(int age, String name) {
        this.age = age;
        this.name =name;
	}
	
	public static void main(String[] args) {
		//TestFunction tfun = new TestFunction(); //创建对象时,new + 该类的构造函数
		TestFunction tfun_1 = new TestFunction(10);
		tfun_1.eat();
		tfun_1.sleep();
		sleep();//在静态main方法中,可以直接访问 对象的静态方法
	}

4.方法重载


重载指,同一个类内多个方法名相同,但方法的形参不同。即:

  1. 参数个数不同;
  2. 参数类型不同;
  3. 参数顺序不同。

重载规则:

  • 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。
public class TestVar {
	public void speak(String language) {};
		public int speak(int c1, int c2) {return 0;};
	public static void speak(int count) {};
	private void speak(String content, int count) {};
	void speak(String content, int language) {};
}

类定义过程注意点:

  • 在类中只包括:变量的定义+方法的定义;
  • 实例方法:可以访问本类中的任何成员变量及任何成员方法;
  • 类方法(static):只能访问本类中的类成员变量及类成员方法;
  • ——static修饰的方法只能访问本类中同样由static修饰的变量或方法。
  • 类中一般变量定义放在类的前面,方法定义放在后面;但变量的定义、方法的定义顺序随意;

第五章讲课逻辑:

  1. 面向对象是什么?
  2. 建立面向对象的思维,了解什么是 类和对象?它们的关系是什么?
  3. 定义第一个类(人类:姓名\年龄\性别 吃饭\睡觉 )-->变量和方法(方法的语法格式\void的概念)
  4. 第一个类的简单应用: 创建对象\对象属性的访问\对象方法的访问
  5. 类体中 变量的分类 全局+局部 以及它们的应用-->定义学生类演示
    1. 全局变量: 静态变量(学校)和实例变量(姓名年龄) :应用在main中测试=>访问方式\默认值\变量的修改
    2. 局部变量:方法体\if\for: 计算做加法sum() =>局部变量的作用域\访问必须初始化或赋值在其他方法中 测试 局部变量的作用域; 访问方式必须初始化或赋值 ;
    3. 3)总结 全局和局部的区别 -->优先级问题-->this 关键字的使用(set/get Name).
  6. 方法的分类(3种)
    • 按返回值:void和return\

按参数: 形参和实参的概念

按功能:实例方法\静态方法\构造方法

-->构造方法(语法格式):用来初始化该类的一个新对象,在系统创建对象时自动执行.

-->无参/有参构造函数:系统是否默认/与类名一致/可以有多个构造函数-->重载(方法名一致)