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 修饰除外),实例方法除了本类中的方法,只能 对象.成员 调用
搜索关注公众号「享智同行」,第一时间获取技术干货
Java入门系列-14-深入类和对象的更多相关文章
- Java入门(5)——类和对象还有构造方法
		类 类和对象的概念: 类是对一群具有相同属性.行为的事物的统称. 类是抽象的. 人以类聚 物以群分 对象: 对象是现实生活中的1个具体存在. 看得 ... 
- Java入门系列-18-抽象类和接口
		抽象类 在第16节继承中,有父类 People People people=new People(); people.sayHi(); 实例化People是没有意义的,因为"人"是 ... 
- Java 集合系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
		概要 学完了Map的全部内容,我们再回头开开Map的框架图. 本章内容包括:第1部分 Map概括第2部分 HashMap和Hashtable异同第3部分 HashMap和WeakHashMap异同 转 ... 
- Java 集合系列 14 hashCode
		java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ... 
- Java中直接输出一个类的对象
		例如 package com.atguigu.java.fanshe; public class Person { String name; private int age; public Strin ... 
- 夯实Java基础系列14:深入理解Java枚举类
		目录 初探枚举类 枚举类-语法 枚举类的具体使用 使用枚举类的注意事项 枚举类的实现原理 枚举类实战 实战一无参 实战二有一参 实战三有两参 枚举类总结 枚举 API 总结 参考文章 微信公众号 Ja ... 
- Java入门系列-11-类和对象
		这篇文章为你搞懂类和对象的使用 对象:用来描述客观事物的实体,由一组属性和方法组成,万物皆对象. 属性:就是对象的特征,像身高.体重.颜色 方法:对象的行为,如跑.跳 类:类是模子,定义对象将会拥有的 ... 
- java总结第三次//类和对象2、3
		四.类和对象2 主要内容:Java类的继承.方法的重写.覆盖.访问控制.super 关键字.多态性及其应用 1.继承 要求:Java只支持单继承,不允许多重继承 一个子类只能有一个父类 一个父类可以派 ... 
- Java面向对象 第1节 类和对象
		一.Java 对象和类 面向对象语言三大特性:封装.继承.多态: 对象:描述客观事物的一个实体: 类:类是封装对象的属性和方法的载体,反过来说具有相同属性和行为的一类实体被称为类:类行为:方法:属性: ... 
随机推荐
- Linux常用开发指令
			gcc mysqltest.c -o mysqltest `mysql_config –cflags –libs` 
- silverlight PopupWindow Resizeable兼容问题
			下方第一段代码,在ie11中Resizeable无法生效,而在chrome中运行正常. HtmlPopupWindowOptions options = new HtmlPopupWindowOpti ... 
- android hook getdeceiveid
			很多手机软件使用了手机绑定.QQ,微信等.如果使用了不同的设备,则需要验证码. 要用一台手机来模拟与另一台手机一样环境,估计hook 系统的相关函数可以实现. 想着应该有现成的软件的,例如 smart ... 
- 菜鸟的Xamarin.Forms前行之路——实现按钮的字体图标(可扩展)
			在实际的APP中,带有图标的按钮用到地方还是蛮多的,字体图标往往能更快更生动的传达信息,并且相对于背景图片,字体图标也有着绝对的优势,所以实现按钮的字体图标是值得尝试的. 实现方法:各平台自定义渲染按 ... 
- mongodb高版本与低版本的区别
			mongodb高版本与低版本的区别 一.mongodb引擎: Mongodb 3.0支持用户自定义存储引擎,用户可配置使用mmapv1或者wiredTiger存储引擎. 3.2版本以后默认的开启的是w ... 
- cobbler PXE 安装系统时出现的问题
			cobbler PXE 安装系统时出现的问题 1.安装包未找到.解决方法:ios镜像里没有软件包,换掉该软件包的ios镜像,或者在ks.cfg 文件里删去或注释掉%packages 里指定安装的软件包 ... 
- Android应用-底部导航栏的使用
			目录 1. 设计底部导航栏页面 1.1. 创建必须的文件夹 1.2. 设计主页面 2. 设计逻辑函数 3. 项目展示 底部导航栏是基于Bottom Navigation Bar 插件使用的 这个插件包 ... 
- java 去最后一位字符 str.substring(0,str.length()-1)
			String str = " 中国, 美国 , 意大利 ";String[] arr = str.split(",");for(int i1 =0;i1< ... 
- 【线程】结果缓存实现(future与concurrenthashmap)
			Computable<A,V>接口中生命了一个函数Computable,其输入类型为A,输出类型为V,在ExpensiveFunction中实现的Computable,需要很长时间来计算结 ... 
- es-curl 查询与更新
			1,封装http方法 private function http($url, $data = NULL, $json = false) { unset($res,$curl,$errorno); $c ... 
