5.面向对象(上)

5.面向对象

5.0类与对象

案例:

​ 张老太养了两只猫:一只名字叫小白,今年 3 岁,白色。还有一只叫小花,今年 100 岁,花色。请编写一个程序,输出两只猫的信息。

public class Object1 {
    public static void main(String[] args) {
        //创建Cat的对象
       Cat cat1 =new Cat();
       //对象初始化
        cat1.name="小白";
        cat1.age=3;
        cat1.color="白色";
        //创建Cat的对象
        Cat cat2 =new Cat();
        //对象初始化
        cat2.name="小花";
        cat2.age=100;
        cat2.color="花色";
        //访问对象属性
        System.out.println("第1只猫信息:"+cat1.name+"\t"+cat1.age+"\t"+cat1.color);
        System.out.println("第2只猫信息:"+cat2.name+"\t"+cat2.age+"\t"+cat2.color);
    }
}
//创建Cat类
class Cat{
    //属性
    String name;
    int age;
    String color;
}

如何创建对象:

1)	先声明再创建
Cat cat ; //声明对象 
cat cat = new Cat(); //创建
2)	直接创建
Cat cat = new Cat();

类与对象的关系示意图:

image-20220225094234859

类和对象的区别和联系:

类是抽象的,代表一类事物,比如人类、猫类等。

对象是具体的,代表一个个具体事物, 即实例。

类是对象的模板,对象是类的一个个体,对应一个个实例。

对象在内存中存在形式:

image-20220225094451067

类和对象的内存分配机制:

: 一般存放基本数据类型(局部变量)

: 存放对象(Cat、数组等)

方法区:常量池(常量,比如字符串), 类的加载信息

创建对象的流程:

Cat cat =new Cat();
//对象初始化
cat.name="小白";
cat.age=3;
  1. 加载Cat类的信息(属性和方法),只会加载一次
  2. 在堆中给对象分配空间,进行默认初始化
  3. 把对象的地址赋给cat,cat指向堆中的对象
  4. 进行指定初始化,如:cat.name="小白";

5.1属性

  • 概念:常见叫法还有: 成员变量 、字段(field)

  • 属性是类的一个组成部分,一般是基本数据类型,也可是引用数据类型。

  • 注意事项和细节:

①属性的定义语法同变量一样,示例:访问修饰符 属性类型 属性名;

访问修饰符: 控制属性的访问范围。有四种访问修饰符 public, proctected, 默认, private

②属性如果不赋值,有默认值。

int 、short、byte 、long: 0

float 、double :0.0

char: \u0000

boolean: false

String: null

5.2方法

5.2.1介绍

在某些情况下,我们要需要定义成员方法(简称方法)。比如人类:除了有一些属性外( 年龄,姓名…),我们人类还有一些行为比如:可以说话、跑步…,通过学习,还可以做算术题。这时就要用成员方法才能完成。

class Person{
    //属性
    String name;
    int age;
    //方法
    public void speak(){
        System.out.println("我是一个好人");
    }
}
/*
public void speak(){}:
public 表示方法是公开	
void 表示方法没有返回值
speak 是方法名, () 里是形参列表
{} 里是方法体
*/

方法的调用机制原理:

image-20220225100539876

方法的定义:

访问修饰符 返回数据类型 方法名(形参列表..) {//方法体语句;
	return 返回值;
}

方法注意事项和使用细节:

  • 访问修饰符 (作用是控制 方法使用的范围),如果不写为默认访问

  • 返回数据类型:

    1. 一个方法最多有一个返回值 [思考,如何返回多个结果 :返回数组 ]
    2. 返回值可以是任何类型,包含基本类型和引用类型
    3. 如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值;而且要求返回值类型必须和 return 的值类型一致或兼容
    4. 如果方法是 void,则方法体中可以没有 return 语句,或者 只写 return ;
  • 方法名:遵循驼峰命名法,见名知义

image-20220225101110603

5.2.2方法传参机制

  • 基本数据类型的传参机制

​ 值传递:形参的改变不影响实参。

  • 引用数据类型的传参机制

​ 引用类型传递的是地址,可以通过形参影响实参。

5.3方法递归调用

1.基本介绍: 递归就是方法自己调用自己,每次调用时传入不同的变量。

2.递归能解决什么问题?

image-20220225101834373

//阶乘
public	int factorial(int n) { 
    if (n == 1) {
		return 1;
	} else {
	return factorial(n - 1) * n;
	}
}

3.递归重要规则

image-20220225102130205

//求斐波那契数 1,1,2,3,5,8,13...
public int fibonacci(int n) {
    if( n >= 1){
		if( n == 1 || n == 2) {
            return 1;
		} else {
			return fibonacci(n-1) + fibonacci(n-2);
		}
		} else {
			System.out.println("要求输入的 n>=1 的整数"); 
       		return -1;
	}
}

5.4 方法重载(OverLoad)

  • 基本介绍:java允许同一个类中,多个同名方法的存在,但要求形参列表不一致!

  • 重载的好处: 减轻了起名和记名的麻烦。利于接口编程

  • 注意事项和使用细节:

​ 方法名:必须相同
​ 形参列表:必须不同(形参类型、个数或顺序至少有一个不同,形参名无要求)
​ 返回类型:无要求

class MyCalculator{
    //下面的四个 calculate方法构成了重载
    //方法1
    public int calculate(int n1, int n2)  {
        System.out.println("方法1被调用...");
        return n1 + n2;
    }
    //方法2
    public double calculate(int n1, double n2) {
        System.out.println("方法2被调用...");
        return n1 + n2;
    }
    //方法3
    public double calculate(double n1, int n2) {
        System.out.println("方法3被调用...");
        return n1 + n2;
    }
    //方法4
    public int calculate(int n1, int n2,int n3) {
        System.out.println("方法4被调用...");
        return n1 + n2 + n2;
    }
}

5.5可变参数

基本概念:

​ java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法,可以通过可变参数实现。

基本语法:

访问修饰符 返回类型 方法名(数据类型... 形参名) {

}
//案例 类 HspMethod中,方法 sum 可以计算 2 个数的和,3 个数的和 ,...)
class HspMethod {
	public int sum(int... nums) {
		//System.out.println("接收的参数个数=" + nums.length); 
        int res = 0;
		for(int i = 0; i <= nums.length; i++) { 
            res += nums[i];
		}
		return res;
}
//1. int... 表示接受的是可变参数,类型是 int ,即可以接收多个 int(0-多)
//2. 使用可变参数时,可以当做数组来使用 即 nums 可以当做数组
//3. 可变参数的本质就是数组
//4. 可变参数可以和普通参数类型放在一起,但可变参数要放到最后
//5. 一个参数列表中只能有一个可变参数

5.6作用域

概念:

1.java中主要的变量是属性和局部变量

2.局部变量一般是在方法中定义的变量

3.java作用域的分类

  • 全局变量:
    • 即属性,作用域为整个类
    • 可以被本类或其他类使用
    • 前面可以加修饰符
  • 局部变量:
    • 除属性之外的其他变量,作用域为定义它的代码块中
    • 只能在本类对应的方法中使用
    • 前面不能加修饰符

4.全局变量可以不赋值,直接使用(有默认值);局部变量必须赋值后才能使用(没有默认值)

注意事项和使用细节:

1.局部变量和属性可以重名,访问时遵循就近原则

2.同一个作用域中,例如同一个方法中,两个局部变量不能重名

3.属性生命周期较长,伴随对象创建而创建,销毁而销毁;

局部变量生命周期较短,伴随执行代码块而创建,代码块执行结束就销毁。

String name = "jack";
public void say() {
//细节 属性和局部变量可以重名,访问时遵循就近原则
	String name = "king"; 
	System.out.println("say() name=" + name);
}

5.7构造器

前面在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值;如果现在要求在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做? 这时就可以使用构造器。

基本介绍

基本语法
[修饰符] 方法名(形参列表){ 
	方法体;
}

构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。

它有几个特点:

  1. 方法名和类名相同
  2. 无返回值
  3. 在创建对象时,系统会自动的调用该类的构造器完成对象属性的初始化
  4. 构造器是完成对象的初始化,而不是创建对象
  5. 参数列表 和 方法的规则一样
  6. 一个类可以定义多个不同的构造器,即构造器重载
  7. 如果没有人为定义构造器,系统会自动生成一个默认的无参构造器。
  8. 一旦定义了自己的构造器,默认构造器就被覆盖了,除非显示定义一下。
public class Constructor {
    public static void main(String[] args) {
        Dog m=new Dog("大黄",4);
        System.out.println(m.name);
        Dog n=new Dog("小黑");
        System.out.println(n.name);
    }
}
class Dog{
    String name;
    int age;
    //构造器
    public Dog(String pName,int pAge){
        name=pName;
        age=pAge;
    }
    //构造器重载
    public Dog(String pName){
        name=pName;
    }
class Test{
    // 默认无参构造器,这里显示定义
    Test(){
    } 
}

注意事项和使用细节:

image-20220225140807745

5.8this关键字

this概念:java虚拟机给每个对象分配this,代表当前对象。

public class This01 {
    public static void main(String[] args) {
        Dog dog1 = new Dog("大壮", 3);
        System.out.println("dog1的hashcode=" + dog1.hashCode());
        dog1.info();
        //
        Dog dog2 = new Dog("大黄", 2);
        System.out.println("dog2的hashcode=" + dog2.hashCode());
        dog2.info();
    }
}
class Dog{ //类
    String name;
    int age;
    // public Dog(String dName, int  dAge){//构造器
    // 	name = dName;
    // 	age = dAge;
    // }
    //如果构造器的形参能够直接写成属性名,就更好了
    //但是出现了一个问题,根据变量的作用域原则,构造器的name和age是局部变量,而不是属性
    // 引出this关键字来解决
    public Dog(String name, int  age){//构造器
        //访问本类的属性
        this.name = name;//this.name就是当前对象的属性name
        this.age = age; //this.age就是当前对象的属性age
        System.out.println("this.hashCode=" + this.hashCode());
    }
    public void info(){//成员方法,输出属性信息
        System.out.println(name + "\t" + age + "\t");
    }
}

image-20220225142530612

this 的注意事项和使用细节:

  1. this 关键字可以用来访问本类的属性、方法、构造器
  2. this 用于区分当前类的属性和局部变量
  3. 访问方法的语法:this.方法名(参数列表);
  4. 访问构造器语法:this(参数列表); 注意只能在构造器中访问另外一个构造器, 必须放在第一条语句。
  5. this 不能在类定义的外部使用,只能在类定义的方法中使用。
public class ThisDetails {
    public static void main(String[] args) {
        T t1 = new T();
        t1.f2();
    }
}
class T {
    public T() {//构造器
        this(15);//在构造器中调用另一个构造器
    }
    public T(int n) {
        System.out.println("有参构造器被调用");
    }
    public void f1() {
        System.out.println("方法1被调用");
    }
    public void f2() {
        //调用f1方法
        f1();//方式1
        this.f1(); //方式2
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值