1.2Java基础面向对象(类和对象概念封装继承多态)

Posted Ocean:)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1.2Java基础面向对象(类和对象概念封装继承多态)相关的知识,希望对你有一定的参考价值。

生活角度面向对象:找合适的人做合适的事

生活角度面向过程:亲历亲为,自力更生

类和对象

对象
电脑类我的机械革命
汽车类1949红旗
人类乔布斯,比尔盖茨,马化腾

类:对于一类事物的统称,对当前事务的一些描述,属性描述和行为描述

对象:独立,唯一,特殊的个体

Java中定义类的格式

class ClassName{
    // 属性描述
    // 行为描述
}

要求:

  1. ClassName 使用大驼峰命名法,见名知意
  2. 属性描述,是用于描述当前类拥有的一些特性,可以使用变量,称为成员变量 Field
  3. 行为描述,用于描述当前类可以做的一些事情,可以使用方法,称为成员方法 Method

定义成员变量

class Person {
	// 使用String类型描述Person类的姓名属性
	String name;
	// 使用int类型描述Person类的年龄属性
	int age;
	// 使用char类型数据描述Person类的性别属性
	char gender;
}

定义成员方法

class Person {
	// 使用方法描述Person类的吃饭行为
	public void eat(String food) {
		System.out.println("吃" + food);
	}
	// 使用方法描述Person类的睡觉行为
	public void sleep() {
		System.out.println("睡觉了");
	}
	// 使用方法描述Person类的打豆豆行为
	public void daDOUDOU() {
		System.out.println("吃饭睡觉打豆豆");
	}
}

eclipse快捷键

force模式:ctrl + shift + a 再按一遍切回

类对象使用

创建(new)对象

类名 对象名 = new 构造方法(所需参数);

// 例:获取一个扫描器对象
// 需要先导包 
import java.util.Scanner;

Scanner sc = new Scanner(System.in);
/* 
数据类型:
	Scanner类型,创建的变量是Scanner的类对象,同时也是一个引用数据类型

sc:
	类对象,变量
	Scanner的类对象,sc是对象名
	
new:
	申请内存的 堆区 空间,并且清理整个空间中的所有数据
	代码中,只要在有new关键字时,一定会用到内存的堆区空间,并且时新的内存空间
	
Scanner(System.in):
	这是一个方法,因为有小括号,没有小括号就是变量
	方法名字和类名一致
	该方法被称为构造方法,Constructor构造方法
*/

新建两个对象

package cn.ocean888;

class Person {
	// 使用String类型描述Person类的姓名属性
	String name;
	// 使用int类型描述Person类的年龄属性
	int age;
	// 使用char类型数据描述Person类的性别属性
	char gender;
}

public class Demo1 {
	public static void main(String[] args) {
		Person ocean = new Person();
		System.out.println(ocean);
		
		Person ocean2 = new Person();
		System.out.println(ocean2);
	}
}

输出结果

image-20210508114922425

  • cn.ocean888 是完整的包名
  • Person 数据类型
  • @15db9742 是当前类对象在内存空间中的首地址,十六进制格式
  • 两个对象的首地址不一致,说明这不是一个对象

调用类成员变量

通过Person类对象,调用类内的成员变量

image-20210508115749743

public class Demo1 {
	public static void main(String[] args) {
		Person ocean = new Person();
		// 赋值
		ocean.name = "ocean";
		ocean.age = 18;
		ocean.gender = '男';
		
		// 取值
		System.out.println("name : " + ocean.name);
		System.out.println("age : " + ocean.age);
		System.out.println("gender :" + ocean.gender);
	}
}

image-20210508120358458

调用类成员方法

类对象.方法名(参数);
package cn.ocean888;

/**
 * 
 * @author q2723
 *
 */
class Person {	
	// 使用方法描述Person类的吃饭行为
	public void eat(String food) {
		System.out.println("吃" + food);
	}
	// 使用方法描述Person类的睡觉行为
	public void sleep() {
		System.out.println("睡觉了");
	}
	// 使用方法描述Person类的打豆豆行为
	public void daDOUDOU() {
		System.out.println("吃饭睡觉打豆豆");
	}
}

public class Demo1 {
	public static void main(String[] args) {
		Person ocean = new Person();
		// 调用类内的eat方法,注意eat有参则需要传入参数
		ocean.eat("bread");
		ocean.sleep();
		ocean.daDOUDOU();
	}
}

image-20210508120858946

内存中的对象

类对象内存分析

对象也是引用传参

类对象内存分析图

注意:char的默认值为 ‘\\0’ null

类对象地址转移

类对象和数组类似,都是引用传参,栈区存储的是首地址

dog1=dog2,就是把dog2首地址给dog1,此时dog1和dog2都指向原dog2的内存空间,原dog1的空间变为无主空间被释放

类对象内存转移问题分析图

构造方法

反编译class文件

找到字节码文件看反编译结果

1.eclipse会自动把.class字节码文件放到指定文件夹

项目名上右击,选择properties

image-20210508140117641

image-20210508140204846

字节码文件在bin目录下

image-20210508140240418

2.在此文件夹打开终端

3.反编译字节码文件命令

Javap -c -l -private .\\Person.class

image-20210508140538966

通过反编译工具,发现一些不存在于原来代码中的内容,这些内容是Java编译器为了方便程序开发,提供的必要的无参数构造方法

Java编译器如果发现当前class没有显式自定义构造方法,回默认提供一个无参数构造方法给予使用

如果java编译器发现代码中存在构造方法,java编译器则不会提供无参构造方法

自定义使用构造方法

构造方法功能:

​ 初始化当前类对象中保存的成员变量数据

new和构造方法作用:

  • new

    1.根据构造方法提供的数据类型申请对应的堆区内存空间

    2.查出整个空间中所有的数据

  • 构造方法

    初始化在当前内存堆区空间的成员变量对应的数据

构造方法的书写格式:

public 类名(初始化形式参数列表) {
    初始化赋值语句;
}

例1:

并没有构造方法,所以Java编译器将提供默认构造方法Cat

package cn.ocean888;

import java.util.Locale.Category;

class Cat {
	String name;
    // 并没有构造方法,所以Java编译器将提供默认构造方法Cat
}

public class Demo2 {
	public static void main(String[] args) {
		// 新建一个cat类
		Cat cat = new Cat();
		cat.name = "huahua";
		System.out.println(cat.name);
	}
}

image-20210508143016270

例2:

有无参构造方法,Java编译器不再提供默认构造方法

package cn.ocean888;

import java.util.Locale.Category;

class Cat {
	String name;
	public Cat() {
		System.out.println("this is constructor");
	}
}

public class Demo2 {
	public static void main(String[] args) {
		// 新建一个cat类
		Cat cat = new Cat();
		cat.name = "huahua";
		System.out.println(cat.name);
	}
}

image-20210508142954109

例3:

存在有参构造方法,不存在无参构造方法的情况

image-20210508143250649

因为此时java编译器发现代码中存在构造方法,java编译器则不会提供无参构造方法,所以箭头指向位置会报错,需要开发者自己写无参构造方法

package cn.ocean888;

import java.util.Locale.Category;

class Cat {
	String name;
	// 无参方法
	public Cat() {
		System.out.println("this is a constructor whitout parameter");
	}
	
	// 有参方法
	public Cat(int age) {
		System.out.println("age:" + age);
	}
	
}

public class Demo2 {
	public static void main(String[] args) {
		// 新建一个cat对象
		Cat cat = new Cat();
		// 新建一个有参对象
		Cat cat2 = new Cat(2);
		cat.name = "huahua";
		System.out.println(cat.name);
	}
}

image-20210508143522784

例4:

带有两个参数的构造方法

package cn.ocean888;

import java.util.Locale.Category;

class Cat {
	String name;
	int age;
	// 无参方法
	public Cat() {
		System.out.println("this is a constructor whitout parameter");
	}
	
	// 有参方法
	public Cat(int age) {
		System.out.println("age:" + age);
	}
	
	// 两个参数的有参方法
	public Cat(int age, String name) {
		name = name;
		age = age;
		System.out.println("有一只" + age + "岁的" + name);
	}
}

public class Demo2 {
	public static void main(String[] args) {
		// 新建一个cat对象
		Cat cat = new Cat();
		// 新建一个有参对象
		Cat cat2 = new Cat(2);
		cat.name = "huahua";
		System.out.println(cat.name);
		
		// 新建一个两个参数的有参对象
		Cat cat3 = new Cat( 5, "加菲猫");
	}
}

image-20210508150755730

总结:

  1. 无论何时类里要有一个无参数构造方法
  2. 根据所需情况完成构造方法参数选择
  3. 一个class可以有多个构造方法(方法的重载)

方法重载

image-20210508151634909

这四个方法特点总结:

  1. 所有方法名字都是一致的
  2. 所有方法参数都不一样
  3. 同一个类内

tips:C语言不允许方法名重复

这就是方法重载

规范:

​ 重载情况下,在同一个类内,不可以出现相同方法名和相同参数数据的方法存在的,只能有一个

原理:

方法名一致的情况下,通过形式参数列表数据类型的不同来选择不同的方法执行

this关键字

就近原则

image-20210508154549864

在构造方法中age,name因为就近原则,会被看做是一个局部变量

此时就应该使用this关键字

this

package cn.ocean888;

class Dog {
	public Dog() {
		System.out.println("address : " + this);
	}
}

public class Demo3 {
	public static void main(String[] args) {
		Dog dog = new Dog();
		System.out.println("address : " + dog);
	}
}

image-20210508155752077

在输出中可以看出来 this 的就是对象首地址,this 指的就是对象本身

这样的话之前就近原则的问题就可以解决了

image-20210508160358115

this.name就是成员变量,而name是局部变量

成员变量和局部变量的对比

image-20210508161915466

补充

零值

new 关键字申请内存空间时,会擦出数据,填入零值

基本数据类型对应的零值

byte short int		 0
long				0L
float				0.0F
double				0.0
char				'\\0' => ascii nul
boolean				false

引用数据类型对应的零值

全部为 null
例:
Person				null
String str			 null
int[] arr			 null

JVM-GC垃圾回收

GC(Garbage Collection)

图书管理员简述回收机制

java中内存管理机制就类似于图书管理员身份

  1. 在单位时间内,检查当前Java程序使用的内存是否存在无主内存
  2. 标记无主内存,多次标记的情况下,会将无主内存内存释放,归还内存空间

优点:

  1. 程序员管理内存更加方便
  2. 内存管理完全自动化

缺点:

  1. 内存回收效率不高
  2. 内存管理出现泄露问题

二分查找

特征:

  • 要求查询的数组必须是一个经过排序之后的数组
  • 查询出多个指定的数据的情况下,无法告知到底是第几个数据出现
  • 没有找到数据返回负数
public class Demo4 {
	public static void main(String[] args) {
		int[] sortedArray = {1,3,5,6,7,8,9,10,11,23};
		int find = 3;
		int result = 0;
		result = halfSearch(sortedArray, find);
		System.out.println(result);
	}
	
	/**
	 * 二分查找
	 * @param sortedArray 要找的数组,数组必须有序 
	 * @param find 在数组中查找的数据
	 * @return 以数字形式返回查找结果,-1表示没有找到,数字表示查找数据所在的位置
	 */
	public static int halfSearch(int[] sortedArray, int find) {
		int minIndex = 0;
		int maxIndex = sortedArray.length;
		int midIndex = (minIndex + maxIndex) / 2;
		while (minIndex <= maxIndex ) {
			if (sortedArray[midIndex] > find ) {
				maxIndex = midIndex - 1;
			} else if (sortedArray[midIndex] < find) {
				minIndex = midIndex + 1;
			} else {
				return midIndex;
			}
			midIndex = (minIndex + maxIndex) / 2;
		}
		return -1;
	}
}
em.out.println(result);
	}
	
	/**
	 * 二分查找
	 * @param sortedArray 要找的数组,数组必须有序 
	 * @param find 在数组中查找的数据
	 * @return 以数字形式返回查找结果,-1表示没有找到,数字表示查找数据所在的位置
	 */
	public static int halfSearch(int[] sortedArray, int find) {
		int minIndex = 0;
		int maxIndex = sortedArray.length;
		int midIndex = (minIndex + maxIndex) / 2;
		while (minIndex <= maxIndex ) {
			if (sortedArray[midIndex] > find ) {
				maxIndex = midIndex - 1;
			} else if (sortedArray[midIndex] < find) {
				maxIndex = midIndex + 1;
			} else {
				return midIndex;
			}
			midIndex = (minIndex + maxIndex) / 2;
		}
		return -1;
	}
}

封装

面向对象三大特征

封装,继承,多态

封装是一个概念,不局限于面向对象的封装

  • 方法的封装
  • 工具类的封装
  • 框架的封装

符合JavaBean规范的类封装过程

要求:

  1. 所有的成员变量全部私有化 ==> private
  2. 必须提供一个无参构造方法
  3. 使用private修饰的成员变量提供对应的操作方法 ==> Setter Getter

private关键字

private关键字是一个权限修饰符

private修饰的成员变量,成员方法,构造方法都是私有化内容,有且只能在类内使用,类外没有任何的操作权限

image-20210509102626700

私有方法不能访问

image-20210509102459899

借助eclipse的outline窗口也可以看到属性和方法的类型

image-20210509102533516

Setter和Getter方法

private修饰的成员变量类外是没有任何操作权限,这里需要提供对应的操作方法,setter和getter方法

Setter方法格式:

public void set成员变量名(对应成员变量的数据类型 成员变量的形式参数) {
	this.成员变量 = 成员变量的形式参数;
}

例如:
public void setName(String name) {
    this.name = name;
}

Getter方法格式:

public 对应成员变量的数据类型 get成员变量名() {
    return 成员变量;
}

例如:
public String getName() {
    return name;
}

tips:

boolean 类型格式规范

例:

// 定义格式
boolean married;

// getter格式
public boolean isMarried() {
    return married;
}

其余数据类型都是getName,setName

自动生成Constructor,Setter,Getter

ctrl + alt + s

  • 生成无参和有参构造方法

image-20210509104741894

image-20210509105005307

  • 生成Getter和Setter

ctrl + alt + s

image-20210509105159602

select all

tips:使用时简写eclipse会自动补齐

image-20210509105512927

生成效果

package com.ocean888;

class Cat {
	
	String name;
	int age;
	char gender;
	boolean married;
	
	// 根据实际需要完成对应Constructor,Setter,Getter
	public Cat() {
		super();
	}


	
	public Cat(String name, int age, char gender, boolean married) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.married = married;
	}



	public String getName() {
		return name;
	}



	public void setName(String name) {
		this.name = name;
	}



	public int getAge() {
		return age;
	}



	public void setAge(int age) {
		this.age = age;
	}



	public char getGender() {
		return gender;
	}



	public void setGender(char gender) {
		this.gender = gender;
	}



	public boolean isMarried() {
		return married;
	}



	public void setMarried(boolean married) {
		this.married = married;
	}
	
}

public class Demo7 {
	public static void main(String[] args) {
		Cat cat = new Cat();
		
		cat.setName("xiaohua");
		cat.setAge(2);
		cat.setGender('雄');
		cat.setMarried(false);
		
		System.out.println("name:" + cat.getName());
		System.out.println("age:" + cat.getAge());
		System.out.println(

以上是关于1.2Java基础面向对象(类和对象概念封装继承多态)的主要内容,如果未能解决你的问题,请参考以下文章

Java面向对象知识(上:基础篇)

04_类和对象

java基础

Java基础02 面向对象

Java基础04_面向对象

Javascript 中的类和对象