zoukankan      html  css  js  c++  java
  • JavaSE(4)

    构造器


    也叫构造方法 ---constructor,本质上是一个方法,但是有特殊性

    特点

    1. 方法名和类名一致, 唯一允许首字母大写的方法名

    2. 没有返回值声明, 甚至连void也不允许

    3. 不能被关键字 : static, final, synchronize, native, abstract等修饰

    4. 不能像普通方法一样随意调用, 只能调用一次. 某个对象的生命周期中只能调用一次.

    总结

    1. **Java****语言中,每个类都至少有一个构造器
    2. 默认构造器的修饰符与所属类的修饰符一致**
    3. 一旦显式定义了构造器,则系统不再提供默认构造器
    4. 类可以创建多个重载的构造器
    5. 父类的构造器不可被子类继承
    6. 构造器重载, 还可以连环调用, 但是一定要保证有一个构造器中是没有this(…). 防止无限递归.

    this()

    • 特殊调用必须是构造器中的第一行. 对其他构造器的调用必须要先于此构造器的特有代码, 最终要体现在继承中子类对象的初始化要晚一些.

    • 在java中,this关键字比较难理解,它的作用和其词义很接近。

    • 它在方法内部使用,即这个方法所属对象的引用;谁调用this就是谁.

    • 它在构造器内部使用,表示该构造器正在初始化的对象。

      注意

      1. **使用this()必须放在构造器的首行!

      2. 使用this调用本类中其他的构造器,保证至少有一个构造器是不用this的。

      3. 	class TeacherV0 { 
        	
        		// 成员变量(member), 成员可以使用修饰符修饰, 注意 : 局部变量无法使用访问控制修饰符 
        		// private表示私有的意思, 一旦私有, 外部无法访问, 只能在类内部访问
        		// 这样的处理称为 "封装", 成员私有化.
        		private String name = "某老师"; // 属性如果没有显式赋值, 它的值就是默认值0
        		private int age; // 缺省值是0
        		private String gender = "未知";
        		
        		// 构造器重载, 还可以连环调用, 但是一定要保证有一个构造器中是没有this(). 防止无限递归.
        		// this(...) 特殊调用必须是构造器中的第一行. 对其他构造器的调用必须要先于此构造器的特有代码
        		public TeacherV0() { // 无参, 调用简单, 功能单一, 有其特殊性, 创建对象简单, 无参构造器将来要为子类专供.
        			/*
        			this.name = "佟刚";
        			this.age = 40;
        			this.gender = "男";
        			*/
        			this("佟刚", 40); // 对其他构造器的调用
        			System.out.println("Teacher()..."); // 此构造器的特有代码
        		}
        		
        		public TeacherV0(String name, int age) {
        			/*
        			this.name = name;
        			this.age = age;
        			this.gender = "男";
        			*/
        			this(name, age, "男"); // 重载的构造器的调用, 必须使用this();
        			System.out.println("Teacher(String, int)...");
        		} 
        		
        		public TeacherV0(String name, int age, String gender) { // 全参, 功能强大, 调用复杂
        			//this();
        			this.name = name;
        			//this.age = age;
        			setAge(age); // 统一的参数合法性判断.
        			this.gender = gender;
        			System.out.println("Teacher(Stintg, int, String)...");
        		}
        		
        		/* 这种方法也是允许存在的, 但是不要这样写, 容易引起误会.*/
        		public void TeacherV0(String name) {
        			System.out.println("我是普通方法, 不是构造方法, 我是捣乱的, 忽略我");
        		}
        		
        		// set方法有参无返回
        		public void setName(String name) { // 间接设置属性的方法,称为set方法
        			//name = name; // 变量访问的就近原则, 会导致左面的name不是属性, 而是局部变量.
        			this.name = name; 
        			// this表示当前对象. 当局部变量参数和成员变量冲突时, 成员变量必须加上限定
        		}
        		
        		// get方法无参有返回
        		public String getName() { // 间接获取name属性值的方法, 称为get方法
        			return this.name;
        		} 
        		
        		// 使用方法间接给属性赋值的好处是 可以加上 逻辑判断, 使得数据得到保护...
        		public void setAge(int age) {
        			if (age < 0 || age > 150) { // 如果数据非法, 直接弹栈
        				System.out.println("参数年龄太大");
        				return; // 提前弹栈, 会导致this.age没有刷新值. 保持了原有的0
        			}
        			this.age = age;
        		}
        		
        		public int getAge() {
        			return this.age;
        		}
        		
        		public void setGender(String gender) {
        			this.gender = gender;
        		}
        		
        		public String getGender() {
        			return this.gender;
        		}
        		
        		// 成员方法(member)
        		public void lesson() {
        			System.out.println(this.say() + "老师在上课"); // 成员互访
        		}
        		
        		public void eat(String some) {
        			System.out.println(name + "老师在吃" + some);
        		}
        		
        		// 返回对象的详细信息字符串, 所有属性值的拼接
        		public String say() {
        			return "姓名 : " + name + ", 年龄 : " + age + ", 性别 : " + gender;
        		}
        }
        
        

    每日一考_day08

    1. 什么是封装? 如何封装?

    成员私有化, 防止外部直接访问. 成员包括属性, 方法, 构造器, 内部类.

    使用private修饰成员, 就可以封装.

    1. 什么是构造器,作用是什么? 有什么特点(4点)

      也称为构造方法, 在对象的创建过程中会由JVM调用它, 作用是对对象进行初始化工作

      • 方法名必须和类名一致, 唯一允许使用首字母大写的方法.
      • 不声明返回值类型, 甚至连void也没有.
      • 不能被关键字:abstract, static ,final, synchronized, native等 修饰
      • 不能像普通方法一样随意调用, 只能在对象创建时调用仅有的一次.
    2. 创建一个对象的步骤(7步)

      1. 在方法区要检查要创建的对象所属的类模板信息是否存在(类是否已经加载)
      2. 如果不存在, 必须由类加载器加载类模板, 加载到方法区中, 永久保存它.
      3. 如果存在, 则不加载, 保证类模板在方法区中只有一份.
      4. 依据类模板中的所有属性定义信息, 在GC区中开辟空间. 获取到对象的地址.
      5. 把此空间全部写0. 底层操作 : memset(内存地址, 0, 长度); 效果是所有属性拥有0
      6. 检查属性是否有显式赋值, 如果有, 则执行显式赋值.
      7. 执行构造方法, 进一步对属性进行赋值等初始化工作.
      8. 把对象地址返回给创建者
    3. this关键字表示什么含义?

      this表示的是对象, 当前对象

      1. 如果是在构造器中, this表示正在创建中的对象, this.成员.
      2. 如果是在构造器中, this(…) 表示对其他重载的构造器的调用.

      要求 :

      1. this(…) 必须在构造器的首行,

      2. 一定要保证至少有一个构造器中没有this(…);

        1. 如果是在方法中或属性的使用中, 表示的是正在访问这个属性或方法的对象的引用
        Xxx ref1 = new Xxx();
        ref1.method(); // 对象方法的调用必须要有对象.
        Xxx ref2 = new Xxx();
        ref2.method();
        ref1.field = “值”;
         
        class Xxx {
        
        ​      String field = this.xxx();
        ​      public void method() {
        ​          // ref1.method() 调用中, this 代表就是ref1
        ​          // ref2.method() 调用中, this 代表就是ref2
        	}
        
        }
        

        this 就是指调用者对象

        对象 包括属性, 或者说是拥有属性

        对象地址 : 对象在GC区中的第一个字节的编号. 也称为首地址

    对象关联

    对象关联 : 一个对象完全拥有另外一个类的对象.

    关联目的 : 随时随时地方便地使用另一个对象.

    如何关联 : 在前者的类中把另外一个类的对象作为属性即可. 属性是成员, 成员意味着它们之间可以直接互访

    一旦把对象作为我的属性, 需要处理全参构造器, 因为是属性也要提供get/set方法, 改造say()方法

    public class Teacher {
    	
    	private String name;
    	private int age;
    	private String gender;
    	private Computer myComputer; // 对象关联
    	
    	public Teacher() {}
    	
    	public Teacher(String name, int age, String gender, Computer myComputer) {
    		this.name = name;
    		this.age = age;
    		this.gender = gender;
    		this.myComputer = myComputer;
    	}
    	
    	public void setMyComputer(Computer myComputer) {
    		this.myComputer = myComputer;
    	}
    	
    	public Computer getMyComputer() {
    		return myComputer;
    	}
    	
    	public void setName(String name) {
    		this.name = name;
    	}
    	
    	public String getName() {
    		return name;
    	}
    	
    	public void setAge(int age) {
    		this.age = age;
    	}
    	
    	public int getAge() {
    		return age;
    	}
    	
    	public void setGender(String gender) {
    		this.gender = gender;
    	}
    	
    	public String getGender() {
    		return gender;
    	}
    	
    	public String say() {
    		return "姓名 : " + name + ", 年龄 : " + age + ", 性别 : " + gender + ", 我的电脑 : " + myComputer.say();
    	}
    	
    	//public void lesson(Computer computer) {
    	public void lesson() {
    		System.out.println(name + "老师在使用电脑[" + myComputer.say() + "]上课");
    	}
    	
    	public void film() {
    		System.out.println("使用电脑[" + myComputer.say() + "]看电影");
    	}
    	
    }
    

    package

    • 包 : 用于管理功能类似的多个类.

    ​ package 包名.子包名.子子包名.子子子包名; // 这个语句总是在源文件中第一行

    • 作用 : 告诉编译器, 当前源文件中的类, 编译后的.class文件放入指定的包目录中.

    ​ 通常情况下包有4层

    ​ package 机构类型.机构名称.项目名称.模块名称; // 包名全部小写

    ​ package com.atguigu.javase.javabean;

    • 一旦使用了package, 会带来两个麻烦

      ​ 1. 编译时必须加上选项-d : javac -d 目标目录路径 源文件名

    ​ -d表示目标目录

    ​ 常见写法 : javac 空格 -d 空格 . 空格 源文件名

    ​ 2. 使用时, 如果是跨包使用本类, 在别的包的类中必须使用全限定名称来使用本类,

    ​ 全限定名称就是 所有包名.类名 : 包名.子包名.子子包名.子子子名包.类名;

    ​ 比如在测试类中, 要想使用本类. com.atguigu.javase.javabean.Teacher

    ​ 练习 : 把Person类和Phone类都打包在com.atguigu.javase.javabean包中

    ​ 把PersonTest类打包在com.atguigu.javase.test包中

    ​ 在测试类中, 使用全限定类名来使用Person类和Phone类, 编译所有程序, 运行测试.

    数组

    • 数组 : 一组相同任意类型的数据的组合, 便于统一管理.

    • 数组 : 由多个元素组成, 每个元素相当于是数组对象的属性

    • 数组属于引用类型, 数组的数据则是对象.

    • 数组声明 :

    ​ 元素数据类型[] 数组名;

    • 数组创建 :

    ​ 数组名 = new 元素数据类型[元素个数];

    public class ArrayTest {
    	
    	public static void main(String[] args) {
    		// 声明 : 元素数据类型[] 数组名;
    		int[] arr; // 此时没有数组对象存在的.
    		// 创建 : new 元素数据类型[元素个数];
    		arr = new int[5]; // 在GC区中创建一个元素有5个的int型数组. 数组对象创建好以后, 所有元素都有缺省值0
    		// 数组元素的定位(访问), 通过首地址(数组名)[偏移量(也称为下标, 索引, 脚标)]
    		// 每个元素都是一个小变量.
    		arr[2] = 4;
    		arr[0] = 3;
    		arr[arr[0]] = 1;
    		arr[arr[2]] = 5;
    		// 分析每个元素的值
    		System.out.println(arr[0]); // 3
    		System.out.println(arr[1]); // 0
    		System.out.println(arr[2]); // 4
    		System.out.println(arr[3]); // 1
    		System.out.println(arr[4]); // 5
    	}
    }
    
    

    每日一考_day09


    1. 类模版信息保存在内存中的什么位置,里面包含了哪些信息,类模版信息的特点和作用是什么?

      在堆内存的永久区(方法区)

      类模版中包含的信息有:

      • 属性的定义信息(修饰符,数据类型,属性名,显示值)
      • 所有方法的代码。(不是在运行中的状态),如果要运行,必须把它压入栈中执行。
      • 构造器,类名、父类、接口、注解。。。
    2. 数组是什么? 什么类型的数据可以创建数组?

      一组相同任意类型的数据的组合,便于统一管理

      任意数据类型,包括基本型和引用型

    3. 如何声明并创建数组?有几种方式?

      声明: 数据类型[] 数组名;

      创建: new 元素数据类型[长度];

      声明和创建 : 元素数据类型[] 数组名 = new 元素数据类型[长度];

      静态方式1 :适用于数据量小,元素值确定的情况

      ​ 元素数据类型[] 数据名 = new 元素数据类型[]{值1,值2......};

      静态方式2 : 使用受限:声明和初始化必须在同一条语句上才可以这样

      ​ 元素数据类型[] 数组名 = {元素值1 ,值2 .....};

    4. 判断

      • 数组的长度可以随意变化 F
      • 数组的元素类型和数组类型是一回事 F
      • 数组的访问是通过数组名.下标实现的 F
      • 数组的访问方式是数组名(首地址)+ 偏移量算出来的 T
      • 数组的元素类型可以随意变化 F
    Student[] stuArr = new Student[3]; // 1
    
    stuArr[0] = new Student(20,"小明","男");
    
    stuArr[1] = new Student(30,"小丽","女");
    
    for (int i = 0;i < stuArr.length;i++){
    	System.out.println(stuArr[i].say());
    }
    

    在1位置处有几个对象被创建,什么对象? 1,String[]

    以上的代码有没有问题?如何改进? 有问题

    • 将stuArr[2]赋上值(Student对象)
    • 加判断语句,若为null不say()即可
  • 相关阅读:
    微软WP7本地数据库之Sqlite编程技巧(转)
    AutoResetEvent详解
    桥接模式的简单分析
    解决VS2008 调试启动特别慢
    软件概要设计
    解决windows8不能安装ZUNE的问题
    CDATA的对特殊字符作用说明
    DataTable对象在内存中的使用(二)
    DataTable对象在内存中的使用(一)
    关于MVC3 CODE FIRST的安装
  • 原文地址:https://www.cnblogs.com/earnest-jie/p/12597917.html
Copyright © 2011-2022 走看看