【Java复健指南05】构造器与作用域
构造器
public class Constructor01{
public static void main(String[] agrs){
//当我们new一个对象时,直接通过构造器指定名字和年龄
Person p1 = new Person("smith", 80);
System.out.println("p1的信息如下");
System.out.println("p1对象name=" + p1.name); //smith
System.out.println("p1对象age=" +p1.age);//80
//添加构造器之后,类在实例化时必须初始化其属性
//实际上不写构造器java也会默认创建一个空构造器
}
}
//在创建人类的对象时,就直接指定这个对象的年龄和姓名1/
class Person {
String name;
int age;
//构造器
//1.构造器没有返回值,也不能写void
//2.构造器的名称和类Person—样
//3. (String pName, int pAge)是构造器形参列表,规则和成员方法一样
public Person(String pName, int pAge){
System.out.println("构造器被调用~~完成对象的属性初始化");
name = pName;
age = pAge;
}
}
注意事项和使用细节
1.一个类可以定义多个不同的构造器,即构造器重载比如:我们可以再给Person类定义一个构造器,
用来创建对象的时候,只指定人名,不需要指定年龄
2.构造器名和类名要相同
3.构造器没有返回值
4.构造器是完成对象的初始化,并不是创建对象
5.在创建对象时,系统自动的调用该类的构造方法
6.如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造方法).比如Dog(){}.可以使用javap指令反编译查看
7.一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非显式的定义一下,即:Person(){}
public class ConstructorDetail{
public static void main(String[] agrs){
Person p1 = new Person("king", 40);//第1个构造器
Person p2 = new Person("tom");//第2个构造器
}
}
class Dog{
/*
默认构造器Dog(){
}
*/
}
class Person {
String name;
int age;//默认0
//第1个构造器
public Person(String pName, int pAge) {
name = pName;
age = pAge;
}
//第2个构造器,只指定人名,不需要指定年龄
public Person(String pName){
name = pName;
}
}
例子
public class ConstructorExercise{
public static void main(String[] agrs){
/*
在前面定义的Person类中添加两个构造器:
第一个无参构造器:利用构造器设置所有人的age属性初始值都为18
第二个带pName和pAge两个参数的构造器:使得每次创建Person对象的同时初始化对象的age属性值和name属性值。
分别使用不同的构造器,创建对象.
*/
Person p1 = new Person();
Person p2 = new Person("ag", 24);
}
}
class Person{
int age;
String name;
public Person(){
System.out.println("构造器1被调用~~完成age的属性初始化");
age = 18;
}
public Person(String pName, int pAge){
System.out.println("构造器2被调用~~完成对象的属性初始化");
name = pName;
age = pAge;
}
}
练习1
public class Homework09{
public static void main(String[] agrs){
/*
9.定义Music类,里面有音乐名name、音乐时长times属性,
并有播放play功能和返回本身属性信息的功能方法getlnfo.
*/
}
}
class Music{
String name;
int times;
public Music(String name, int times) {
this.name = name;
this.times = times;
}
//播放play功能
public void play(){
System.out.println("音乐" + name +"正在播放中...时长为"+ times +"秒")}
//返回本身属性信息的功能方法getInfo
public String getInfo(){
return "音乐"+name +"播放时间为" +times;
}
}
练习2
public class Homework12{
public static void main(String[] agrs){
/*
12.创建一个Employee类,属性有(名字,性别,年龄,职位,薪水),
提供3个构造方法,可以初始化
(1)(名字,性别,年龄,职位,薪水),
(2)(名字,性别,年龄)
(3)(职位,薪水).要求充分复用构造器
*/
}
}
class Employee{
String name;
String sex;
int age;
String zhiwei;
int sal;
public Employee(String name, String sex, int age, String zhiwei, int sal){
this.name = name;
this.sex = sex;
this.age = age;
this.zhiwei = zhiwei;
this.sal = sal;
}
public Employee(String name, String sex, int age){
this.name = name;
this.sex = sex;
this.age = age;
}
public Employee(String zhiwei, int sal){
this(name,gender, age);//使用到前面的构造器
this.zhiwei = zhiwei;
this.sal = sal;
}
}
作用域
基本使用
面向对象中,变量作用域是非常重要知识点
1.在java编程中,主要的变量就是属性(成员变量)和局部变量。
2.我们说的局部变量一般是指在成员方法中定义的变量。【举例Cat类: cry】
3.java中作用域的分类
全局变量:也就是属性,作用域为整个类体Cat类: cry eat等方法使用属性
局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中!
4.全局变量(属性)可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能用,因为没有默认值。
public class Scope01{
public static void main(String[] agrs){
}
}
class cat {
//全局变量:也就是属性,作用域为整个类体Cat类 :cry eat等方法使用属性
//属性在定义时,可以直接赋值
int age = 10;//指定的值是10
// {
// int num = 100;//仅能在该代码块中使用
// }
double weight;//不赋值 默认值是0.0
public void cry(){
//1.局部变量一般是指在成员方法中定义的变量
//2. n和name就是局部变量
//3. n和name的作用域在cry方法中
int n = 10;
String name = "jack";
System.out.println("在cry中使用属性age=" +age);
}
public void eat() {
system.out.println("在eat中使用属性age="+age);
// System.out.println("在eat中使用cry的变量 name=" + name);//错误
}
}
注意事项
1.属性和局部变量可以重名,访问时遵循就近原则。
2.在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。
3.属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而死亡。
局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。即在一次方法调用过程中。
4.作用域范围不同
全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
局部变量:只能在本类中对应的方法中使用
5.修饰符不同
全局变量/属性可以加修饰符局部变量不可以加修饰符
public class ScopeDetail{
public static void main(String[] agrs){
}
}
class T {
//全局变量
//属性:可以被本类使用,或其他类使用(通过对象调用)
public void test(){
Person p1 = new Person();
System.out.println(p1.name); //jack
}
public void test2(Person p){
system.out.print1n(p.name); //jack
}
}
class Person{
//属性可以加修饰符,局部变量不能
public int age = 18;
String name = "jack";
public void say(){
//属性和局部变量可以重名,访问时遵循就近原则
String name = "king";
System.out.println("say() name = "+ name);
}
public void hi(){
String address = "北京";
String name = "hyn";
}
}
This
This理解:
new新对象p1之后会在堆中开辟新空间(设为k1),k1中会保存对象里面的值(比如name,age等),同时会生成一个隐藏变量this,该变量指向空间本身.此时this.name指的就是k1中的name,对应p1的对象属性
简单地说,“哪个对象调用,this就代表哪个对象”
public class This01{
public static void main(String[] agrs){
Dog dog1 = new Dog("大社", 3);
System.out.println("dog1的hashcode=" + dog1.hashCode());
//dog1调用了info()方法
dog1.info();
System.out.println("============");
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就是局部变量了而不是属性
//相当于传入的参数只是在构造器这的name,和类的属性没关系,
//因此打印的时候还是打的默认值
public Dog(String name, int age){//构造器
// name = name;
// age = age;
//this.name就是当前对象的属性name
this.name = name;
//this.age就是当前对象的属性age
this.age = age;
System.out.println("this(Dog).hashCode=" + this.hashCode());
}
public void info(){ System.out.println("this(info).hashCode=" + this.hashCode());
System.out.println(name + "\t" + age + "\t");
}
}
this的注意事项和使用细节
1. this关键字可以用来访问本类的属性、方法、构造器
2. this用于区分**当前类的属性**和**局部变量**
3. 访问成员方法的语法:this.方法名(参数列表)
4. 访问构造器语法:this(参数列表);注意只能在构造器中使用
5. **this不能在类定义的外部使用**,只能在类定义的方法中使用。
public class ThisDetail{
public static void main(String[] agrs){
// T t1 = new T()
// t1.f2();
T t2 = new T();
}
}
class T{
/*
细节:访问构造器语法:this(参数列表);
注意只能在构造器中使用(即只能在构造器中访问另外一个构造器)
ps:访问构造器语法:this(参数列表);必须放在第一条语句
*/
public T() {
System.out. println("T()构造器");//这里去访问 T(String name,int age)
this("jack", 100);
}
public T(String rgme, int age){
System.out.println("T(String name,int age)构造器");
}
//this关键字可以用来访问本类的属性
public void f3(){
String name = "smith";
//传统方式,就近原则name为sm,因为局部变量没有num就回属性去拿
System.out.println("name=" +name + " num=" + num); // smith 100
//也可以使用this访问属性,回属性去拿
System.out.println("name=" + this.name + " num=" + this.num);//jack 100
}
//访问成员方法的语法:this.方法名(参数列表准)
public void f1(){
System.out.println("f1() 方法..");
}
public void f2(){
System.out.println("f2() 方法..");
//调用本类的f1
//第一种方式
f1();
//第二种
this.f1();
}
}
例子
public class ThisExercise{
public static void main(String[] agrs){
Person p1 = new Person("ts", 20);
Person p2 = new Person("ag", 24);
//p1输入的参数为this,p2的为比较值
System.out.println("p1和p2比较的结果="+ p1.compareTo(p2));
}
}
class Person{
int age;
String name;
//构造器
public Person(String name, int age){
this.name = name;
this.age = age;
}
public boolean compareTo(Person p){
// if(p.name == this.name && p.age == this.age){
// return true;
// }else{
// return false;
// }
//简化写法
return this.name.equals(p.name) && this.age == p.age;
}
}