编程语言
首页 > 编程语言> > 面向对象编程---上(start)

面向对象编程---上(start)

作者:互联网

学习面向对象内容的三条主线

1.Java类及类的成员:属性、方法、构造器;代码块、内部类

2.面向对象的三大特征:封装性、继承性、多态性、(抽象性) 

3.其他关键字:this、super、static、final、abstract、interface、package、import等

原则:“大处着眼,小处着手”

一、面向过程与面向对象  

例子:“人把大象装进冰箱”
  
  1. 面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。
  ① 把冰箱门打开
  ② 抬起大象,塞进冰箱
  ③ 把冰箱门关闭
  2. 面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
  人{
          打开(冰箱){
              冰箱.开开();
          }
          抬起(大象){
              大象.进入(冰箱);
          }
          关闭(冰箱){
              冰箱.闭合();
          }
  }  
  冰箱{
          开开(){}
          闭合(){}
 }
  大象{
          进入(冰箱){
          }
 }  

二、Java基本元素:类和对象

类:对一类事物的描述,是抽象的、概念上的定义

对象:是实际存在的该类事物的每个个体,因而也称为实例(instance)

        >可以理解为:类 = 抽象概念的人; 对象 = 实实在在的某个人

        >面向对象程序设计的重点是类的设计

        >设计类,就是设计类的成员

                属性 = 成员变量 = field = 域、字段

                方法 = 成员方法 = 函数 = method

类和对象的使用(面向对象思想落地的实现):
   1.创建类,设计类的成员
   2.创建类的对象
   3.通过“对象.属性”或“对象.方法”调用对象的结构

三、对象的创建(new)和使用(.)

创建类的对象 = 类的实例化 = 实例化类

调用对象的结构:属性、方法
        调用属性:“对象.属性”

        调用方法:“对象.方法”

如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。(非static的)
意味着:如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。

对象的内存解析:

编译完源程序以后,成成一个或多个字节码文件。

我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。(内存解析是在运行时进行的!)

 

堆(heap):存放对象的实例,例如所有new出来的东西、数组

栈(stack):我们在java中常说的栈通常是指虚拟机栈,用于存放局部变量

方法区:存放加载的类信息、常量、静态变量

一个关于Person类的测试代码 

public class PersonTest {
	public static void main(String[] args) {
		//创建Person类的对象
		Person p1 = new Person();
		Person p2 = new Person();
		//类似Scanner scanner = new Scanner(System.in);
		p1.name = "Tom";
		p1.isMale = true;
		System.out.println(p1.name);
		
		p1.eat();
		p1.sleep();
		p1.talk("Chinese");
		
		System.out.println(p2.name);
		System.out.println(p2.isMale);
		
		Person p3 = p1;
		System.out.println(p3.name);
		p3.age = 10;
		System.out.println(p1.age);
	}
}

class Person{
	
	//属性
	String name;
	int age = 1;
	boolean isMale;
	
	//方法
	public void eat() {
		System.out.println("人可以吃饭");
	}
	
	public void sleep() {
		System.out.println("人可以睡觉");
	}
	
	public void talk(String language) {
		System.out.println("人可以说话,说的是:" + language);
	}
	
	
}

四、类的成员之一:属性

 * 类中属性的使用
 * 
 * 属性(成员变量)   vs  局部变量
 * 1.相同点:
 *         1.1  定义变量的格式:数据类型  变量名 = 变量值
 *         1.2 先声明,后使用
 *         1.3 变量都有其对应的作用域 
 * 
 * 2.不同点:
 *         2.1 在类中声明的位置的不同
 *         属性:直接定义在类的一对{}内
 *         局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
 *         
 *         2.2 关于权限修饰符的不同
 *         属性:可以在声明属性时,指明其权限,使用权限修饰符。
 *             常用的权限修饰符:private、public、缺省、protected  --->封装性
 *             目前,大家声明属性时,都使用缺省就可以了。
 *         局部变量:不可以使用权限修饰符。
 *   
 *         2.3 默认初始化值的情况:
 *         属性:类的属性,根据其类型,都有默认初始化值。
 *             整型(byte、short、int、long):0
 *             浮点型(float、double):0.0
 *             字符型(char):0  (或'\u0000')
 *             布尔型(boolean):false
 * 
 *             引用数据类型(类、数组、接口):null
 * 
 *         局部变量:没有默认初始化值。
 *         意味着,我们在调用局部变量之前,一定要显式赋值。
 *         特别地:形参在调用时,我们赋值即可。
 * 
 *         2.4 在内存中加载的位置:
 *         属性:加载到堆空间中(非static)
 *         局部变量:加载到栈空间

测试代码---UserTest

public class UserTest {
	public static void main(String[] args) {
		User u1 = new User();
		System.out.println(u1.name);	
		System.out.println(u1.name);	
		System.out.println(u1.name);	
		}

}

class User{
	String name;
	int age;
	boolean isMale;
	
	public void talk(String language) {
		System.out.println("我们使用" + language + "进行交流");
	}
	
	public void eat() {
		String food = "烙饼";
		System.out.println("北方人喜欢吃: " + food);
	}
}

五、类的成员之二:方法

 类中方法的声明和使用
  
  方法:描述类应该具有的功能。

 
   比如:

      Math类:sqrt()\random() \...
      Scanner类:nextXxx() ...
      Arrays类:sort() \ binarySearch() \ toString() \ equals() \ ...

快捷键:

Ctrl + Shift + t

Ctrl + o

  1.举例:
  public void eat(){}
  public void sleep(int hour){}
  public String getName(){}
  public String getNation(String nation){}
  2. 方法的声明:权限修饰符  返回值类型  方法名(形参列表){
                      方法体
                } 
    注意:static、final、abstract 来修饰的方法,后面再说。
    
  3. 说明:
          3.1 关于权限修饰符:默认方法的权限修饰符先都使用public
              Java规定的4种权限修饰符:private、public、缺省、protected  -->封装性再细说
  
          3.2 返回值类型: 有返回值  vs 没有返回值
              3.2.1  如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,                         需要使用return关键字来返回指定类型的变量或常量:“return 数据”。
                       如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法                         中就不需要使用return.但是,如果使用的话,只能“return;”表示结束此方法的意思

                3.2.2 我们定义方法该不该有返回值?

                  ① 看题目要求        ② 凭经验:具体问题具体分析

           3.3 方法名:属于标识符,遵循标识符的规则和规范,“见名知意”        

           3.4 形参列表: 方法可以声明0个,1个,或多个形参。

                 3.4.1 格式:数据类型1 形参1,数据类型2 形参2,...

                 3.4.2 我们定义方法时,该不该定义形参?

                ① 题目要求        ② 凭经验:具体问题具体分析

          3.5 方法体:方法功能的体现。

4.return关键字的使用:
     1.使用范围:使用在方法体中
     2.作用:① 结束方法
                   ② 针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。
     3.注意点:return关键字后面不可以声明执行语句。

5. 方法的使用中,可以调用当前类的属性或方法

      特殊的:方法A中又调用了方法A:递归方法。
      方法中,不可以定义方法!!!。

测试代码---CustomerTest

public class CustomerTest {
	public static void main(String[] args) {
		Customer cust1 = new Customer();
		
		cust1.eat();
		cust1.sleep(8);
	}
}

class Customer{
	
	String name;
	int age;
	boolean isMale;
	
	public void eat() {
		System.out.println("客户吃饭");
		return;//此处表示结束该方法
		//return后不可以声明表达式
		
//		System.out.println("hello");
	}
	
	public void sleep(int hour) {
		System.out.println("休息了" + hour +"个小时");
		eat();
//		sleep(10);
	}
	
	public String getname() {
		
		if (age > 18) {
			return name;
		}else {
			return "Tom";
		}
	}
	
	public String getNation(String nation) {
		String info = "我的国籍是:" + nation;
		return info;
	}
	
	public void info(){
		//不能在方法里再定义一个方法
//		public void swim() {
//			
//		}
	}
}

练习题

  1.1 创建一个Person类

public class Person {
	
	String name;
	int age;
	/**
	 * sex:0表明是女性
	 * sex:1表明是男性
	 * 
	 */
	int sex;
	
	public void study() {
		System.out.println("studying");
	}
	
	public void showAge() {
		System.out.println("age:" + age);
	}
	
	public int addAge(int i) {
		age += i;
		return age;
	}
}

 1.2 创建一个PersonTest类 

public class PersonTest {
	public static void main(String[] args) {
		Person p1 = new Person();
		
		p1.name = "Tom";
		p1.age = 18;
		p1.sex = 1;
		
		p1.study();
		
		p1.showAge();
		
		int newAge = p1.addAge(2);
		System.out.println(p1.name + "的新年龄为:" + newAge);
		
		System.out.println(p1.age);
		
		Person p2 = new Person();
		p2.showAge();
		p2.addAge(10);
		p2.showAge();
		p1.showAge();
		
		
	}
}

 

public class CircleTest {
	public static void main(String[] args) {
		
		Circle c1 = new Circle();
		
		c1.radius = 3.1;
		
		//对应方式一:
//		double area = c1.findArea();
//		System.out.println(area);
		
		c1.findarea();
	}
}


class Circle{
	double radius;
	
	//求圆的面积
	//方式一:
//	public double findArea() {
//		double area = Math.PI * radius * radius;
//		return area;
//	}
	
//	方式二:
	public void findarea() {
		double area = Math.PI * radius * radius;
		System.out.println("面积为:" + area);
	}
		
}

 

public class Exer3Test {
	public static void main(String[] args) {
		Exer3Test test = new Exer3Test();
		//3.1测试
//		test.method();
		
		//3.2测试
		//方式一:
//		int area = test.method();
//		System.out.println("面积为:" + area);
		
		//方式二:
//		System.out.println(test.method());
		
		//3.3测试
		int area = test.method(12, 10);
		System.out.println("面积为:" + area);
	}
	
	// 3.1
//	public void method() {
//		for (int i = 0; i < 10; i++) {
//			for (int j = 0; j < 8; j++) {
//				System.out.print("* ");
//			}
//			System.out.println();
//		}
//	}
	
	//3.2
//	public int method(){
//		for (int i = 0; i < 10; i++) {
//			for (int j = 0; j < 8; j++) {
//				System.out.print("* ");
//			}
//			System.out.println();
//		}
//		
//		return 10 * 8;
//	}
	
	//3.3
	public int method(int m, int n) {
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				System.out.print("* ");
			}
			System.out.println();
		}
		return m * n;
	}
}

 

 

public class StudentTest {
	public static void main(String[] args) {
		
		//声明Student类型的数组
		Student[] stus = new Student[20];
		
		for (int i = 0; i < stus.length; i++) {
			//给数组元素赋值
			stus[i] = new Student();
			//给Student对象的属性赋值
			stus[i].number = i + 1;
			//假设年级:[1, 6]
			stus[i].state = (int)(Math.random() * (6 -1 + 1) + 1);
			//成绩:[0, 100]
			stus[i].score = (int)(Math.random() * (100 - 0 + 1) + 0);
		}
		
		//遍历学生数组
		for (int i = 0; i < stus.length; i++) {
//			System.out.println(stus[i].number + "," + stus[i].state + "," + stus[i].score);
			System.out.println(stus[i].info());
		}
		
		System.out.println("*************");
		
		//问题一:打印出3年级(state值为3)的学生信息。
		for (int i = 0; i < stus.length; i++) {
			if (stus[i].state == 3) {
				System.out.println(stus[i].info());
			}
		}
		
		System.out.println("###########");
		
		//问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
		for (int i = 0; i < stus.length - 1; i++) {
			for (int j = 0; j < stus.length - 1 - i; j++) {
				if (stus[j].score > stus[j+1].score) {
					Student temp = stus[j];
					stus[j] = stus[j + 1];
					stus[j + 1] = temp;
				}
			}
		}
		
		for (int i = 0; i < stus.length; i++) {
			System.out.println(stus[i].info());
		}
		
	}

}



class Student{
	int number; //学号
	int state;
	int score;
	
	//显示学生信息的方法
	public String info() {
		return "学号:" + number + ",年级:" + state + ",成绩:" + score;
		
	}
}

代码改进:将操作数组的功能封装到方法中

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

		// 声明Student类型的数组
		Student2[] stus = new Student2[20];

		for (int i = 0; i < stus.length; i++) {
			// 给数组元素赋值
			stus[i] = new Student2();
			// 给Student对象的属性赋值
			stus[i].number = i + 1;
			// 假设年级:[1, 6]
			stus[i].state = (int) (Math.random() * (6 - 1 + 1) + 1);
			// 成绩:[0, 100]
			stus[i].score = (int) (Math.random() * (100 - 0 + 1) + 0);
		}

		StudentTest2 test = new StudentTest2();
		// 遍历学生数组
		test.print(stus);
		System.out.println("*************");

		// 问题一:打印出3年级(state值为3)的学生信息。
		test.searchState(stus, 3);
		System.out.println("###########");

		// 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
		 test.sort(stus);
		 test.print(stus);
	}
	

	/**
	* @Title: print 
	* @Description: 遍历Student2[]数组的操作
	* @param  stus  要遍历的数组 
	* @return void    返回类型
	 */
	public void print(Student2[] stus) {
		for (int i = 0; i < stus.length; i++) {
//					System.out.println(stus[i].number + "," + stus[i].state + "," + stus[i].score);
			System.out.println(stus[i].info());
		}
	}
/**
* 
* @Title: searchState 
* @Description: 查找Student2[]数组中指定年级的信息
* @param  stus 要查找的数组
* @param  state  要找的年级 
* @return void    返回类型
*/
	public void searchState(Student2[] stus, int state) {
		for (int i = 0; i < stus.length; i++) {
			if (stus[i].state == state) {
				System.out.println(stus[i].info());
			}
		}
	}
	
	/**
	 * 
	* @Title: sort 
	* @Description: 给Student2[]数组排序
	* @param stus  要排序的数组 
	* @return void    返回类型
	 */
	public void sort(Student2[] stus) {
		for (int i = 0; i < stus.length - 1; i++) {
			for (int j = 0; j < stus.length - 1 - i; j++) {
				if (stus[j].score > stus[j + 1].score) {
					Student2 temp = stus[j];
					stus[j] = stus[j + 1];
					stus[j + 1] = temp;
				}
			}
		}
	}

}

class Student2 {
	int number; // 学号
	int state;
	int score;

	// 显示学生信息的方法
	public String info() {
		return "学号:" + number + ",年级:" + state + ",成绩:" + score;

	}
}

 补充:冒泡排序算法的实现

/*
 * 数组冒泡排序的实现
 * 
 */
public class BubbleSort {
	public static void main(String[] args) {
		
		int[] arr = new int[] {12,35,35,79,-56,-35,88,20,0,21};
		
		//冒泡排序
		 for(int i = 0; i < arr.length - 1; i++) {
			 
			 for (int j = 0; j < arr.length - 1 - i; j++) {
				if(arr[j] > arr[j + 1]) {
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp; 
				}
			}
		 }
		
		
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + "\t");
		}
	}
}

 复习题:

1. 面向对象思想编程内容的三条主线分别是什么?

① 类及类的成员:属性、方法、构造器;代码块、内部类

② 面向对象的三大特征:封装、继承、多态 

③ 其它关键字:this,super,abstract,interface,static,final,package,import

面向对象的编程思想?

(类、对象;面向对象的三大特征(封装、继承、多态);。。。)

2. 谈谈你对面向对象中类和对象的理解,并指出二者的关系

类:抽象的、概念上的内容

对象:实实在在存在的一个个体。

对象是由类派生出来(new出来)的。(对象是类的实例化)

3. 面向对象思想的体现一:类和对象的创建和执行操作有哪三步?

① 创建类

② 类的实例化

③ 调用对象的结构:”对象.属性” “对象.方法”

4. 画出如下代码在执行时的内存分配情况

class Car{

       String color = "red";

       int num = 4;

       void show(){

               int a = 10;

          System.out.println("color="+color+",num="+num);

        }

  }

class CarTest {

public static void main(String[] args) {

      Car c1 = new Car();  

      Car c2 = new Car();

          c1.color = "blue"; 

          c1.show();  

          c2.show();

}

5. 类的方法内是否可以定义变量?是否可以调用属性?是否可以定义方法?是否可以调用方法?

是;是;否;是

6. 完成一个项目(或功能)的思路:

7. 回归变量的分类:

        方式一:按照数据类型

        方式二:按照在类中声明的位置

 

  

理解“万事万物皆对象”

1.在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构

         >Scanner,String等
         >文件:File
         >网络资源:URL
 2.涉及到Java语言与前端Html、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象。

内存解析的说明
  1.引用类型的变量,只可能存储两类值:null  或  地址值(含变量的类型)


  
匿名对象的使用
  1.理解:我们创建的对象,没有显式的赋给一个变量名。即为匿名对象
  2.特征:匿名对象只能调用一次
  3.使用:如下

public class Instance {
	public static void main(String[] args) {
		Phone p = new Phone();
//		p = null;
		System.out.println(p);
		
		p.sendEmail();
		p.playGames();
		
		//匿名对象
//		new Phone().sendEmail();
//		new Phone().playGames();
		
		new Phone().price = 1999;
		new Phone().showPrice();//0.0
		System.out.println("**********");
		
		PhoneMall mall = new PhoneMall();
		//匿名对象的使用,此时将地址值其实是赋给了形参phone
		//此时调用的是同一个对象
		mall.show(new Phone());
	}
}

class PhoneMall{
	
	public void show(Phone phone) {
		phone.sendEmail();
		phone.playGames();
	}
}


class Phone{
	double price;
	
	public void sendEmail() {
		System.out.println("发邮件");
	}
	
	public void playGames() {
		System.out.println("玩游戏");
	}
	
	public void showPrice() {
		System.out.println("手机价格为:" + price);
	}
}

 工具类的封装:

 1.1造工具类ArrayUtil

public class ArrayUtil {

	// 求数组的最大值
	public int getMax(int[] arr) {
		int maxValue = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (maxValue < arr[i]) {
				maxValue = arr[i];
			}
		}
		return maxValue;
	}

	// 求数组的最小值
	public int getMin(int[] arr) {
		int minValue = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (minValue > arr[i]) {
				minValue = arr[i];
			}
		}
		return minValue;
	}

	// 求数组的总和
	public int getSum(int[] arr) {
		int sum = 0;
		for (int i = 0; i < arr.length; i++) {
			sum += arr[i];
		}
		return sum;
	}

	// 求数组的平均值
	public int getAvg(int[] arr) {
		return getSum(arr) / arr.length;
	}

	// 翻转数组
	public void reverse(int[] arr) {
		for (int i = 0; i < arr.length / 2; i++) {
			int temp = arr[i];
			arr[i] = arr[arr.length - i - 1];
			arr[arr.length - i - 1] = temp;
		}
	}

	// 复制数组
	public int[] copy(int[] arr) {
		int[] arr1 = new int[arr.length];
		for (int i = 0; i < arr1.length; i++) {
			arr1[i] = arr[i];
		}
		return arr1;
	}

	// 数组排序
	public void sort(int[] arr) {
		// 冒泡排序
		for (int i = 0; i < arr.length - 1; i++) {

			for (int j = 0; j < arr.length - 1 - i; j++) {

				if (arr[j] > arr[j + 1]) {
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}

			}

		}
	}

	// 遍历数组
	public void print(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + "\t");
		}
		System.out.println();
	}

	// 查找指定元素
	public int getIndex(int[] arr, int dest) {
		// 线性查找:

		for (int i = 0; i < arr.length; i++) {

			if (dest == arr[i]) {
				return i;
			}
		}
		
		return -1; //返回一个负数表示没有找到
		}
	}

1.2工具类的测试ArrayUtilTest

public class ArrayUtilTest {
	public static void main(String[] args) {
		
		ArrayUtil util = new ArrayUtil();
		int[] arr = new int[]{32,20,5,-8,0,99,5,-899};
		int max = util.getMax(arr);
		System.out.println("最大值为:" + max);
		
//		System.out.println("排序前:");
//		util.print(arr);
//		
//		util.sort(arr);
//		
//		System.out.println("排序后:");
//		util.print(arr);
//		
//		System.out.println("查找:");
		int index = util.getIndex(arr, -5);
		if (index >= 0) {
			System.out.println("找到了,索引地址为:" + index);
		}else {
			System.out.println("没找到");
		}
	}
}

 

六、再谈方法

方法的重载(overload)  loading...

  1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
     
 "两同一不同":同一个类、相同方法名
            参数列表不同:参数个数不同,参数类型不同
 
  2. 举例:
    Arrays类中重载的sort() / binarySearch()
 
  3.判断是否是重载:
    跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
    
  4. 在通过对象调用方法时,如何确定某一个指定的方法:
      方法名 ---> 参数列表

七、OOP特征一:封装与隐藏

八、类的成员之三:构造器

九、关键字:this

十、关键字:package、import

标签:stus,arr,int,System,---,start,面向对象编程,public,out
来源: https://blog.csdn.net/m0_59157761/article/details/120386062