Java面向对象零散笔记(二)

简介

  1. 封装性:内部的操作对外部而言不可见
    继承性:在上一辈的基础上继续发展
    多态性:在可控范围内的状态改变

  2. OOA(面向对象分析)
    OOD(面向对象设计)
    OOP(面向对象编程)

面向对象的特征:可以进行生活的抽象

类与对象

  1. 声明并实例化对象:类名称 对象名称 = new 类名称();
  1. 对象只有实例化(new)以后才可以真正使用

  2. 引用类型指的是内存空间的操作:

    • 堆内存空间:保存真正的数据,保存的是属性信息
    • 栈内存空间:保存的堆内存的地址,堆内存的操作权
  3. 一个栈内存只能保存一个堆内存地址
    一块堆内存可以被多个栈内存所指向

  4. NullPointerException:只有引用数据类型才会产生此类异常

  5. 垃圾空间:指的是没有任何栈内存指向的堆内存空间,所有垃圾空间将定期被Java的垃圾收集器进行回收,以实现内存空间的释放

private实现封装处理

  1. 使用private声明后属性安全了,如果想要进行private私有属性的访问,按照Java设计原则,可使用setter、getter方法:
    • setter方法:主要用于进行属性内容的设置 / 修改
    • getter方法:主要用于属性内容的取得

构造方法与匿名对象

  1. 可以利用构造方法传递属性的内容(初始化),以避免重复的setter调用

  2. 匿名对象:
    如,new Person("Bob",30).getName()
    由于匿名对象不会有任何的栈内存,使用一次之后就会变成垃圾空间

  3. Java简单类:

    • 类中所有方法尽量不用System.out.语句,所有的输出交给调用处
    • 应该提供有一个返回类完整信息的方法,如getInfo()。

数组的定义和使用

  1. 数组的访问通过索引完成,即:“数组名称[索引]”

  2. 动态初始化格式:
    数据类型 数组名称 [ ] = new 数据类型 [ 长度 ]
    静态初始化格式
    数据类型 数组名称 [ ] = new 数据类型 { 值,值,值...}

  1. 数组采用动态初始化开辟空间后,数组里面的每一个元素都是该数组对应数据类型的默认值

  2. 数组是有序、有限的集合
    缺点:长度固定

  3. 如果要发生引用传递,等号右侧不要出现 “ [ ] ”

  4. 二维数组的输出,外部循环控制输出的行数,内部循环控制输出的列数

  5. Java对数组的支持:

    • 数组排序:java.util.Arrays.sort();

      public static void sort(int arr[]){
             
      	for(int x = 0; x < arr.length - 1 ; x ++){
             
      		for( int y = 0; y < arr.length - x - 1; y ++){
             
      			if (arr[y] > arr[y+1]){
             
      				int temp = arr[y];
      				arr[y] = arr[y+1];
      				arr[y+1] = temp;
      		}
      	}
      }
      
    • 数组拷贝:将一个数组的部分内容替换掉另外一个数 组的部分内容System.arraycopy(源数组名称,源数组开始点,目标数组名称,目标数组开始点,拷贝长度)

  6. 主方法相当于客户端调用,里面的代码应该越简单越好

  7. 数组反转:

    • 思路1:创建等长数组
      缺点:开辟了两块相同的堆内存空间。造成空间浪费
    • 思路2:数组长度 / 2,在一个数组上完成
      public static void reverse(int arr[]){
             
      	int center = arr.length / 2;
      	int head = 0;
      	int tail = arr.length - 1;
      	for ( int x = 0; x < center; x++){
             
      		int temp = arr[head];
      		arr[head] = arr[tail];
      		arr[tail] = temp;
      		head++;
      		tail--;
      	}
      }
      
  8. 二维数组转置的前提:行列相等(x==y)

  9. 数组二分法查找(前提:数组排序):
    采用方法递归完成

    public static int binarySearch(int arr[], int from. int to, int key){
         
    	if (from < to){
         
    		int mid = (from / 2)+ (to / 2);
    		if ( arr[mid] == key){
         
    			return mid;
    		}else if (key < arr[mid]){
         						
    			return binarySearch(arr, from, mid-1, key);
    		}else if (key >arr[mid]){
         
    			returnbinarySearch(arr, mid+1, to, key);
    		}
    	}else{
         
    		return -1;
    	}
    }
    
  10. 对象数组

String类的基本特点

  1. 直接以赋值的形式声明:String a = " ";
    传统形式声明:String a = new String(" ");

    两种实例化区别:
    1⃣️直接赋值:如,str1 = "hello"; str2 = "hello"; str3 = "hello";,并不会开辟新堆内存空间,原因在于String类的设计使用了一个共享设计模式,在JVM的底层实际上会自动维护一个对象池,如果采取直接赋值的模式进行String类对象的实例化操作,那么该实例化对象(字符串)将自动滴保存到这个对象池之中,如果下次继续有人使用了直接赋值的模式声明了String类的对象。如果此时对象池中有指定的内容,将直接进行引用;如果没有,则开辟新的字符串对象并保存在对象池之中,以供下次使用
    2⃣️使用构造方法:标准做法,但有一块堆内存空间将会成为垃圾空间,此外该方法还会对字符串共享产生问题,需要手动处理进入对象池,如String str1 = new String("hello").intern();
    在这里插入图片描述

  2. 字符串比较:

    • “ == ”比较:本质上是地址数值比较,比较是否指向同一个堆内存
    • “equals”比较:内容的比较,str1.equals(str2);
  3. 字符串常量是String的匿名对象
    System.out.println("hello".equals(str));

提示:在日后开发过程中,如果要判断用户输入的字符串是否等同于指定字符串,那么一定要将字符串写在前面,即"hello".equals(input)

  1. 字符串常量不可变更
    所有语言对于字符串的底层实现都是字符数组(数组的最大缺陷就是长度固定)
    !对字符串改变过多会形成大量垃圾空间

  2. 字符串和字符数组的相互转换,如
    char data [ ] = str.toCharArray();
    String str2 = new String(data);

  3. 字节与字符串:
    (用户数据传输以及编码转换处理之中)
    字节并不适合处理中文,只适用于处理二进制数据

  4. 字符串比较:
    equalsIgnoreCase(String str);不区分大小写比较
    compareTo(String str);比较大小关系,返回int(相等:返回0;小于:返回的内容小于0;大于:返回的内容大于0),即两者编码值的差

  5. 字符串查找:
    contains()indexOf()lastIndexof()fromIndexOf()startsWith()endsWith()

  6. 字符串替换:
    replaceAll()replaceFirst()
    字符串的替换操作与正则有关

  7. 字符串拆分:
    split()
    如果发现有些内容无法拆分开,就需要使用“ \ ”转义

  8. 字符串截取:
    subString(int beginIndex)subString(int beginIndex, int endIndex)
    截取的索引从0开始,且只能设置正整数

  9. 其他操作方法:
    trim():去掉字符串中的左右空格,保留中间空格
    toUpperCase():字符串转大写(不是字母的不转换,实际上就少了用户的判断)
    intern():字符串的入池方法
    concat():字符串连接,等同于“ + ”
    length():取得字符串长度
    isEmpty():判断字符串是否为空字符串,返回 true / false

  10. String类没有提供首字母大写的方法:

    public static String initcap(
    String str){
         
    	if(str == null || "".equals(str)){
         
    		return str;
    	}
    	if(str.length() > 1){
         
    		return str.substring(0,1).toUpperCase() + str.substring(1);
    	}
    	return str.toUpperCase();
    }
    

this关键字

  1. 调用本类属性:
    参数与属性同名问题:为了明确标记处要使用的是属性还是方法的参数,建立属性前同一加上this.

  2. 调用本类方法:

    • 普通方法:this.方法名称(参数…)
    • 构造方法:this(参数…)
      (1) Java支持类构造方法的互相调用
      (2) this()调用构造方法的语句必须放在构造方法的首行(不要产生递归构造调用?)
      (3) 使用this调用构造方法的时候要留有出口
  3. 表示当前对象(相对概念)
    在一个类中会产生若干个对象,程序类在分辨的时候不会记住具体有多少个对象产生了,它唯一可能知道的当前操作本类的对象是哪一个

    在整体的操作过程中,this定义没有变,只要有某一个对象调用了本类中的方法,那么这个this就表示当前执行的对象

引用传递分析

  1. 字符串常量一旦声明则不可改变,字符串的内容改变依靠的是地址的引用关系变更

    public class TestDemo{
         
    	public static void main(String args[]){
         
    		String str = "hello";
    		fun(str);
    		System.out.println(str);
    	}
    	public static void fun (String temp){
         
    		temp = "world";
    	}
    }
    //输出hello
    
  2. 传参

    class Message{
         
    	private String note;
    	public void setNote(String note){
         
    		this.note = note;
    	}
    	public String getNote(){
         
    		return this.note;
    	}
    }	
    
    public class TestDemo{
         
    	public static void main(String args[]){
         
    		Message msg = new Message();
    		msg.setNote("hello");
    		fun(msg);
    		System.out.println(msg.getNote());
    	}
    	public static void fun (Message temp){
         
    		temp.setNote("world");
    	}
    }
    //输出world;
    
  3. 对象比较需要根据对象所拥有的属性信息来进行完整比对,该功能应该是一个类本身所具备的功能,而不应该变为外部的操作。

    class Person{
         
    	private int age;
    	private String name;
    	
    	public Person(int age, String name){
         
    		this.name = name;
    		this.age = age;
    	}
    
    	public boolean compare( Person per){
         
    		if ( per == this){
         
    			return true;
    		}  else if ( per == null){
         
    			return false;
    		} else if ( this.name.equals( per.name) && this.age == per.age){
         
    			return true;
    		} 
    	}
    }
    
    public class TestDemo{
         
    	public static void main(String args[]){
         
    		Person perA = new Person("Bob",20);
    		Person perB = new Person("Bob",20);
    		if (perA.compare(perB)){
         
    			System.out.println("两个对象相等!")
    		} else {
         
    			System.out.println("两个对象不等!")
    		}
    	}
    }
    
  4. 引用传递,可以更好的表现出现实世界的抽象【40 】

数据表与简单Java类

  1. 实际开发中的简单Java类设计原则
    · 简单Java类的名称 = 实体表名称;
    · 简单Java类的属性 = 实体表的字段;
    · 简单Java类的一个对象 = 表的一行记录
    · 对象数组 = 表的多行记录
    · 外键关系 = 引用配置

  2. 举例(一对多):

一个部门有多个雇员,并且可以输出一个部门的完整信息(包括雇员信息);可以根据一个雇员找到雇员对应的领导信息和雇员所在部门信息

Step1 先按照给定的关系将所有的基础字段转化为类
Step2 进行关系设计,该数据表中对应有如下几个关系:
	· 一个雇员属于一个部门:追加部门引用
	· 一个雇员有一个领导:追加自身关联
	· 一个部门有多个雇员:追加对雇员象数组描述
Step3 实现开发的需求
	class Emp{
   
		private int eno;
		private String ename;
		private String job;
		private double salary;
		private double comm;

		private Emp mgr // 描述雇员领导
		private Dept dept//描述雇员所在部门
		
		public Emp(){
   };
		
		public Emp(int eno, String ename, String job, double salary, double comm){
   
			this.eno = eno;
			this.ename = ename;
			this.job = job;
			this.salary = salary;
			this.comm = comm;
		}

		public void setMgr(Emp mgr){
   
			this.mgr = mgr;
		}

		public Emp getMgr(){
   
			return mgr;
		}

		public void setDept(Dept dept){
   
			this.dept = dept;
		}

		public Dept getDept(){
   
			return dept;
		}

		public String getInfo(){
   
			return "【EMP】empo = " + this.eno + ",ename = "+ this.ename + ". job = " + this.job + ", salary = " + this.salary + ", comm = " + this.comm;
		}
	}
	class Dept{
   
		private int dno;
		private String dname;
		private String loc;

		private Emp [] emps; //所有雇员

		public Dept(){
   };
		public Dept(int dno, String dname, String loc){
   
			this.dno = dno;
			this.dname = dname;
			this.loc = loc;
		}

		public void setEmps(Emp [] emps){
   
			this.emps = emps;
		}
		public Emp [] getEmps(){
   
			return this.emps;
		}
		public String getInfo(){
   
			return  "【DEPT】dno = " + this.dno + ",dname = "+ this.dname + ". loc = " + this.loc;
		}
	}

public class TestDemo{
   
	public static void main(String args[]){
   
		//第1:设置类对象间的关系
		//(1):分别创建各自类的实例化对象
		Dept dept = new Dept(10, "Accounting", "NY");
		Emp ea = new Emp(0001, "Smith", "Clerk", 800.0, 0.0);
		Emp eb = new Emp(0002, "Allen", "Manager". 2450.0, 0.0);
		Emp ec = newEmp(0003, "King", "President", 5000.0, 0.0);
		//(2):设置雇员领导的关系
		ea.setMgr(eb);
		eb.setMgr(ec);
		//(3):设置雇员部门的关系
		ea.setDept(dept);
		eb.setDept(dept);
		ec.setDept(dept);
		//(4):设置部门雇员的关系
		dept.setEmps(new Emps[] {
   ea,eb,ec});
		//第2:进行数据的取得
		System.our.println(dept.getInfo());
		for (int x = 0 ; x < dept.geyEmps().length; x ++){
   
			System.out.println("\t|-"+dept.getEmps()[x].getInfo());
			if ( dept.getEmps()[x].getMgr() != null){
   
				System.out.println("\t\t|-"+dept.getEmps()[x].getMgr().getInfo());
			}
		}
		System.out.println("===============");
	}
}
  1. 举例(多对多):

——定义一个学生选择的操作表:
· 学生表 | 学生编号、姓名、年龄
· 课程表 | 课程编号、课程名、学分
· 学生-课程关系表 |学生编号、课程编号、成绩
——要求可以实现如下信息输出:
· 找到一门课程以及参加此课程的所有学生信息及其成绩
· 可以根据一个学生,找到他所参加的所有课程和每门课程的成绩

class Student{
   
	private int stuid;
	private String name;
	private int age;
	private StudentCourse studentCourses[];

	public Student(){
   }
	public Student(int stuid, String name. int age){
   
		this.stuid = stuid;
		this.name = name;
		this.age = age;
	}
	
	public void setStudentCourses(StudentCourse[] studentCourses){
   
		this.studentCourses = studentCourses;
	}
	public StudentCourse[] getStudentCourses(){
   
		return this.studentCourses;
	}

	public String getInfo
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值