zoukankan      html  css  js  c++  java
  • Java入门系列-14-深入类和对象

    这篇文章用大量的代码帮你搞懂:值传递和引用传递、构造方法、方法重载、static关键字的使用

    方法参数传递-值传递和引用传递

    1.值传递

    敲一敲:

    /**
     * 使用方法交换两个变量的值
     * @author Jack
     *
     */
    public class Swap {
    	public static void main(String[] args) {
    		int a=10;
    		int b=8;
    		Swap swap=new Swap();
    		swap.swap(a, b);
    		System.out.println("调用方法后:a="+a+",b="+b);
    	}
    	public void swap(int a,int b) {
    		int temp=a;
    		a=b;
    		b=temp;
    		System.out.println("交换后:a="+a+",b="+b);
    	}
    }
    

    在上面这段代码中我们发现在方法内部对这两个参数进行交换成功,但是在调用方法后外部变量并没有任何变化。参数的类型为值类型,使用值类型作为参数称为值传递。

    值传递方法内部修改外部不保留,参数内的变量是实参的副本。

    2.引用传递

    敲一敲:

    import java.util.Arrays;
    public class Swap2 {
    	public static void main(String[] args) {
    		int[] ages= {1,2,3};
    		Swap2 swap=new Swap2();
    		System.out.println("调用change前:"+Arrays.toString(ages));
    		swap.change(ages);
    		System.out.println("调用change后:"+Arrays.toString(ages));
    	}
    	public void change(int[] ages) {
    		ages[0]=100;
    	}
    }
    

    在方法内部对参数变量进行修改后,方法的外部打印后也进行了修改,数组、类都是引用类型,使用引用类型作为参数传参被称为引用传递。

    引用传递方法内部修改外部保留,参数内的变量是对实参的引用。

    构造方法

    在创建对象的时候,我们使用过这样的代码 类名 对象名=new 类名(); ,其实这时就是在调用此类的构造方法 public 类名(){}

    构造方法又称构造函数,是类中一种特殊的方法。构造方法名与类名相同,不返回任何值,主要完成对象的初始工作。

    语法:

    访问修饰符 构造方法(可以指定参数){
        //初始化代码
    }
    

    敲一敲:无参构造方法

    public class Student {
    	String name;
    	int age;
    	public Student() {
    		name="张三";
    		age=18;
    	}
    	public static void main(String[] args) {
    		Student stu=new Student();
    		System.out.println(stu.name);
    		System.out.println(stu.age);
    	}
    }
    

    这样就能在 new 时给对象的属性初始化值,但是在每一次 new 的时候都是相同的值。能不能在 new 的同时指定值呢?那就是使用有参的构造方法。

    敲一敲:有参构造方法

    public class Student {
    	String name;
    	int age;
    	public Student(String name,int age) {
    		this.name=name;
    		this.age=age;
    	}
    	public static void main(String[] args) {
    		Student stu=new Student("张三",12);
    		System.out.println(stu.name);
    		System.out.println(stu.age);
    	}
    }
    

    this 代表当前对象的引用,在有参构造方法中使用时区分属性和参数

    上面的这段代码,能不能这样创建对象 Student stu=new Student();

    答案是不可以的

    不显式编写构造方法,系统将默认提供无参构造方法
    一旦提供编写构造方法,系统便不再提供无参构造方法

    所以这时我们可以同时编写有参构造方法和无参构造方法,使我们创建对象的时候更加的灵活。

    敲一敲:同时提供有参和无参构造方法

    public class Student {
    	String name;
    	int age;
    	//无参构造方法
    	public Student() {}
    	//有参构造方法
    	public Student(String name,int age) {
    		this.name=name;
    		this.age=age;
    	}
    	public static void main(String[] args) {
    		//使用有参构造方法
    		Student stu1=new Student("张三",12);
    		System.out.println(stu1.name);
    		System.out.println(stu1.age);
    		//使用无参构造方法
    		Student stu2=new Student();
    		stu2.name="李四";
    	}
    }
    

    方法重载

    在上一部分中,我们使用了有参和无参的方法,为什么在一个类中可以定义多个类名相同的方法呢?因为实现了方法重载。只不过构造方法重载是一种特殊的重载。

    重载的条件(两同两不同)

    在同一个类中,方法名相同,参数类型不同,参数个数不同

    敲一敲:实现普通方法的重载

    public class Teacher {
    	public void teach(String project) {
    		System.out.println("教授科目:"+project);
    	}
    	public void teach(String project1,String project2) {
    		System.out.println("教授科目:"+project1+" 和 "+project2);
    	}
    	public static void main(String[] args) {
    		Teacher t=new Teacher();
    		t.teach("语文");
    		t.teach("语文","数学");
    	}
    }
    

    在生活中有很多活动就属于重载,比如 表演 ,给表演者剧本就是在表演戏剧,给表演者乐器,就是表演演奏,给表演者话筒,就是表演相声。

    在代码中使用重载也有很多好处,比如 System.out.println(); 这个方法也有很多重载形式,可以传入 int string object 作为参数,减少了书写和记忆的成本。你肯定不希望打印每种数据类型时都单独定义一个方法,像后面这样 printIntln(int out) printDoubleln(double out) printLongln(long out) ……

    this 关键字的用法

    在使用构造函数时使用了 this 关键字用于区分属性和参数,那只是第一种用法,除此之外还可以调用方法、调用构造方法。

    调用属性:this.health=100;

    调用方法:this.print();

    调用构造方法:this(); this("张三",18); 必须用在构造方法中的第一行

    static 关键字的用法

    如何通过类名直接访问类中的成员,像之前用过的 Arrays.toString(),查看源码部分代码如下。

    public static String toString(int[] a) {
        if (a == null)
            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";
    
        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(a[i]);
            if (i == iMax)
                return b.append(']').toString();
            b.append(", ");
        }
    }
    

    当前这个方法使用了 static 关键字进行了修饰

    还可以修饰成员变量:

    public class Teacher {
    	static final String SEX_MALE="男";
    	static final String SEX_FEMALE="女";
    	String sex;
    	public static void main(String[] args) {
    		Teacher teacher=new Teacher();
    		teacher.sex=Teacher.SEX_FEMALE;
    		System.out.println(teacher.sex);
    	}
    }
    

    final 修饰后的变量都将变成常量
    常量的值不能修改,只能使用

    可以修饰代码块:

    public class Teacher {
    	static final String SEX_MALE="男";
    	static final String SEX_FEMALE="女";
    	String sex;
    	//代码块
    	static {
    		System.out.println("静态代码块");
    	}
    	public static void main(String[] args) {
    		Teacher teacher=new Teacher();
    		teacher.sex=Teacher.SEX_FEMALE;
    		System.out.println(teacher.sex);
    	}
    }
    

    static 关键字使用注意事项

    1.static 修饰了属性和代码块后,会先初始化静态属性,再执行静态代码块

    public class TakeCare1 {
    	static String name="aa";
    	static {
    		System.out.println(name);
    		System.out.println("静态代码块执行");
    	}
    	public TakeCare1() {
    		System.out.println("构造函数执行");
    	}
    	public static void main(String[] args) {
    		TakeCare1 t=new TakeCare1();
    	}
    }
    

    2.static 关键字不能修饰局部变量

    public class TakeCare2 {
    	public static void main(String[] args) {
    		static int a=10;
    	}
    }
    

    3.同一个类中的静态方法可以互相通过方法名直接调用

    public class TakeCare2 {
    	public static void test1() {
    		System.out.println("method test1");
    		test2();
    		TakeCare2.test2();
    	}
    	public static void test2() {
    		System.out.println("method test2");
    	}
    	public static void main(String[] args) {
    		test1();
    	}
    }
    

    4.不同类中的静态成员调用需要通过 类名.成员 调用

    public class TakeCare4 {
    	public static void main(String[] args) {
    		Test.test();
    		System.out.println(Test.name);
    		//test();//去掉前面注释试试
    	}
    }
    class Test{
    	static String name="Test";
    	public static void test() {
    		System.out.println("method test");
    	}
    }
    

    5.同一个类中非静态方法可以直接通过 属性名或方法名 调用

    public class TakeCare5 {
    	static String name="static property";
    	public static void st() {
    		System.out.println("static method");
    	}
    	public void test() {
    		System.out.println("instance method");
    		System.out.println(name);
    		st();
    	}
    }
    

    6.静态方法不能直接使用实例成员,需要通过对象调用

    public class TakeCare6 {
    	public static void st() {
    		System.out.println("static method");
    		TakeCare6 tc=new TakeCare6();
    		tc.test();
    		//test();//去掉注释后报错 Cannot make a static reference to the non-static method test() from the type TakeCare6
    	}
    	public void test() {
    		System.out.println("instance method");
    	}
    }
    

    总结:static 修饰后的成员就像万能的 O 型血,在任何地方都能 类名.成员 调用(private 修饰除外),实例方法除了本类中的方法,只能 对象.成员 调用

    搜索关注公众号「享智同行」,第一时间获取技术干货

  • 相关阅读:
    Ubuntu系统下adb连接小米
    Android自动化测试工具 calabash-android
    Android
    Android单元测试——Instrumentation
    Linux C语言 文件指针/句柄(FILE*)、文件描述符(fd)以及 文件路径(filepath)的相互转换
    Sublime Text 2 配置
    转: N个Android很有用的代码片段
    图片测试脚本
    数据查找
    小小
  • 原文地址:https://www.cnblogs.com/AIThink/p/9797232.html
Copyright © 2011-2022 走看看