构造方法(构造函数)
构造方法是类里的一个特殊的方法,它不能有返回值(包括void)。所谓构造方法,就是这个类在被实例化时(创建对象时)就要执行的方法,方法名和类名相同,一般的目的是为了给类进行一些初始化值。
构造函数的特点:
1.构造函数的方法名与类名相同。
2.构造函数没有返回类型。
3.构造函数的主要作用是完成对类对象的初始化工作。
4.构造函数不能由编程人员显式地直接调用。
5.在创建一个类的新对象的同时,系统会自动调用
6.该类的构造函数为新对象初始化。
示例:
package com.ambow.test;
public class Demo1 {
//实列变量
String color;
int hit;
int attack;
// 展示方法
public void display() {
System.out.println(color + "命中率为:" + hit + ",攻击值为:" + attack);
}
public void aa(){
System.out.println(color+hit+attack);
}
/**
* 构造函数/方法
* 语法格式:
* 1.构造方法名与类名相同
* 2.构造函数没有返回值类型
* 修饰符 构造方法名([形参列表]){
* [初始值]
*
* 如果不手动添加一个构造器的话,系统默认为我们自动提供一个无参构造器
* 如果一旦手动添加了,那么系统就不在为我们提供无参构造器
* }
* */
//无参构造方法/函数/器
public Demo1(){
//默认值
System.out.println("这是一个无参构造器!!");
}
//有参构造函数
public Demo1(String color,int hit,int attack){
//this代表当前类的对象,如果说能用this.出来的变量就是实列变量,点不出来的变量就是局部变量
this.color=color;
this.hit=hit;
this.attack=attack;
}
public static void main(String[] args) {
//无参构造器
Demo1 dd=new Demo1();
//dd.display();
//有参构造器:通过构造函数进行传值
Demo1 d=new Demo1("蓝色小鸟", 70, 800);
d.display();
d.aa();
}
}
说明:通常我们在new对象的时候,new后面的一般都是类名+括号,其实这个括号表示的就是方法,而这个方法指的就是构造方法,说白了就是我们在创建对象时调用的就是构造方法,一般而言只要我们创建好了类,系统会默认给我们提供一个构造函数,只要你创建对象,那么这个构造方法是自动调用的,当我们手动写一个构造函数时,系统就不再默认给我们提供了。
这里大家还要注意,构造函数可以重复的调用,说白了就是你创建一次对象它就调用一次构造函数,而且都是最原始情况的构造函数,所以说构造函数主要作用是完成对类对象的初始化工作。而且我们在使用构造函数的时候会发现除了创建对象调用构造函数以外,别的情况无法调用构造函数。
6.5 this的使用
this 关键字是 Java 常用的关键字,可用于任何实例方法内指向当前对象,也可指向对其调用当前方法的对象,下面我们提供案例来学习this的使用。
示例:
package com.ambow.test;
public class ThisDemo {
/*
* this的作用:
* 1.表示当前类对象
* 2.当局部变量和实例变量重名时需要使用this来区分
* */
//实例变量
String s;
public void Method(){
System.out.println("this的作用");
}
// 参数
public void Method1(String s){
/*
* 在一个类中我们通常调用当前类的方法都是直接使用方法名
* 其实在这里使用时我们省略了关键字this
* 此时的this就表示的时当前对象,符合类对象调用类方法
* */
this.Method();
/*
* 类中我们定义了实例变量s,在方法中我们定义了参数s,此时实例变量和参数的名字重复
* 这时我们就需要使用this来进行区分
* this能够调用出来的就是实例变量,调用不出来的就是局部变量(参数)
* */
this.s=s;
}
}
说明:这里我们只介绍了this的两种用法。
6.6 值传递和引用传递
函数/方法的参数分为形参和实参两种:
形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用。
实参出现在主调函数中,进入被调函数后,实参变量也不能使用。
形参和实参的功能是作数据传送(赋值)。发生函数调用时,主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。JAVA传递参数有两种方式:值传递和引用传递。值传递是传递数据,引用传递是把形参和实参的指针指向了堆中的同一对象。简单的来说值传递指的就是Java方法的参数是简单类型的时候, 引用传递指的是Java方法的参数是类类型/引用数据类型的时候。
示例:
package com.ambow.test;
public class ChuanDi {
public void add(int a){//a=100
a+=100;//a=200
System.out.println("add:"+a);
}
public void work(Demo1 b){
b.color="绿色小鸟";
b.hit=4000000;
b.attack=22222;
}
//程序的主入口 main方法
public static void main(String[] args) {
//创建对象
ChuanDi cd=new ChuanDi();
/*值传递:其实传递的是一个拷贝的值,跟原来的值没有任何关系,拷贝的值在怎么变化不会影响到原来的值*/
//定义一个int类型的变量a
int a=100;
//把变量a的值传到add方法中
cd.add(a);
System.out.println("main:"+a);
/*引用传递:其实传递的是一个引用(本身),如果传递进去以后对其进行改变,那么他将影响原来的值*/
Demo1 d=new Demo1();
Demo1 d2=d;
System.out.println(d);
System.out.println(d2);
d.color="红色小鸟";
d.hit=50;
d.attack=200;
d.display();
//将引用/对象传递出去
cd.work(d);
d.display();
}
}
说明:此案例关联前一个案例中的方法。我们在进行值传递的时候我们会发现调用完方法以后本身的值并没有发生改变,而引用传递的时候值发生了改变。
6.7 封装
6.7.1 封装的概念
封装指的就是将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
6.7.2 封装的优点
1.只能通过规定方法访问数据
2.隐藏类的实现细节
3.方便加入控制语句
4.方便修改实现
6.7.3 包 package
Java的文件名必须和public的类名相同,为了解决同名的冲突和类的访问权限的控制,Java提供包(package)来来管理类名空间,package语句必须放在Java源文件的第一条语句,指明该文件中定义的类所在的包。
1.包名全部要小写
包的物理意义是:文件夹
包名的命名法则:
商业包:com.公司名.项目名.模块名.层次
开源:org.公司名(个人名).项目名.模块名.层次
教育:edu.公司名(个人名).项目名.模块名.层次
2.导入包:import + 包名 (避免写*)
import java.util.Date;
快捷键为:ctrl+Shift+o
6.7.4 修饰符(成员访问控制符)
对象的成员变量和方法都有访问权限的控制,由于类中封装了数据和代码,包括封装了其他的类和包,所以java对类成员提供了四种范围的访问控制权限的控制
1.同一类中(private)
类中限定为private的成员(属性或者方法),只能被这个类本身访问,即私有访问控制
2.同一包中(默认不写)
类中不写修饰符,代表默认(friedly),在同一类,同一包中都可访问
3.不同包中的子类(protected)
类中限定为 protected 的成员变量和成员方法,可以被这个类本身以及它的子类访问(包括同一包和不同包中的子类都可以访问)
4.不同包中的非子类(public)
对比图:类中被限定为 public 的成员,都是公共的,可以被所有的类访问,它的的访问权限时最大的,但同时也是最不安全的
示例:
同一个包同一个类中:
package com.ambow.a;
public class XiuShiFuDemo {
/*
* 1.访问修饰符private
* 使用private修饰的变量或者方法只能在本类中访问到,其他任何地方都不能访问
* */
//属性
private String loginname;
//方法
private void login(){
}
/*
* 2.访问修饰符默认的
* 使用默认的访问修饰符(前面比价任何访问修饰符的情况)修饰的变量或者方法,只能被同一个包中所有的类访问到
* 如果超出本包,那么就不能访问到(包括不同包的子类)
* */
String password;
void work(){
}
/*
* 3.protected访问修饰符
* 使用protected访问修饰符修饰的变量或者方法,可以在同一个类中,同一个包中和不同包中的子类访问到
* 超出范围则不能被访问
* */
protected int age;
protected void say(){
}
/*
* 4.public访问修饰符
* 使用public访问修饰符只要是在一个项目中,它都能被访到
* */
public String sex;
public void cry(){
}
public static void main(String[] args) {
//创建对象
//private修饰
XiuShiFuDemo xs=new XiuShiFuDemo();
xs.loginname="123";
xs.login();
//默认修饰
xs.password="1";
xs.work();
//protected修饰
xs.age=23;
xs.say();
//public修饰
xs.sex="1";
xs.cry();
}
}
同一个包中的不同类:
package com.ambow.a;
public class Demo {
public static void main(String[] args) {
XiuShiFuDemo xs=new XiuShiFuDemo();
//报错:使用private修饰的变量或者方法只能在本类中访问到,其他任何地方都不能访问
//xs.login="123";
//使用默认的访问修饰符(前面比价任何访问修饰符的情况),只能被同一个包中所有的类访问到
xs.password="123";
xs.work();
//使用protected访问修饰符修饰的变量或者方法,可以在同一个类中,同一个包中和不同包中的子类访问到
xs.age=23;
xs.say();
//使用public访问修饰符只要是在一个项目中,它都能被访到
xs.sex="1";
xs.cry();
}
}
不同包的子类:
package com.ambow.b;
import com.ambow.a.XiuShiFuDemo;
public class Demo extends XiuShiFuDemo {
public static void main(String[] args) {
XiuShiFuDemo xs=new XiuShiFuDemo();
//报错:默认访问修饰符如果超出本包,那么就不能访问到(包括不同包的子类)
//xs.passwprd="123";
//使用protected访问修饰符修饰的变量或者方法,可以在同一个类中,同一个包中和不同包中的子类访问到
Demo d=new Demo();
d.age=23;
d.say();
//使用public访问修饰符只要是在一个项目中,它都能被访到
d.sex="2";
d.cry();
}
}
不同包的非子类:
package com.ambow.c;
import com.ambow.a.XiuShiFuDemo;
public class Demo {
public static void main(String[] args) {
XiuShiFuDemo xs=new XiuShiFuDemo();
//使用protected访问修饰符超出范围则不能被访问
//xs.age=23;
//使用public访问修饰符只要是在一个项目中,它都能被访到
xs.sex="1";
xs.cry();
}
}
6.7.5 封装的set和get
在java中,有一种常见的做法,就是将成员变量用private修饰,从而更好的将信息进行封装和隐藏,在这样的类中,用getXXX 和setXXX 方法对类的属性进行存取,我们把这样的类叫JavaBean
优点:
1.属性用private更好的封装和隐藏,外部类不能随意存取和修改
2.提供方法来存取对象的属性,在方法中可以对给定的参数进行合法性检验
3.方法可以用来给出计算后的值
4.方法可以完成其他必要的工作(如:清理资源,设定状态等)
5.只提供getXXX而不提供setXXX,保证属性的只读性
示例:(定义)
package com.ambow.d;
/**
* 封装:1.将信息私有化(使用private修饰)
* 2.为私有属性提供公共的get和set方法
* */
public class Player {
private String loginname;//表示玩家用户名
private String password;//表示密码
private String nickname;//表示玩家昵称
private String sex;//表示玩家性别
private int age;//表示玩家年龄
private int chushu;//表示除数
//合法校验
public int getChushu() {
return chushu;
}
public void setChushu(int chushu) {
if(chushu==0){
System.out.println("除数不能为零!!");
}else{
this.chushu = chushu;
}
}
//赋值方法:set
public void setLoginname(String loginname){
this.loginname=loginname;
}
//取值方法:get
public String getLoginname(){
return this.loginname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
示例:(使用)
package com.ambow.d;
public class Demo {
public static void main(String[] args) {
// 创建玩家对象pla
Player pla = new Player();
// 利用对象调用赋值(set)方法,对属性进行赋值
pla.setLoginname("郭德纲");
pla.setPassword("123");
pla.setNickname("admin");
pla.setSex("男");
pla.setAge(12);
System.out.println("玩家用户名\t玩家密码\t玩家昵称\t玩家性别\t玩家的年龄");
// 利用对象调用取值(get)方法,将属性的值获取出来
System.out.println(pla.getLoginname() + "\t" + pla.getPassword() + "\t"
+ pla.getNickname() + "\t" + pla.getSex() + "\t"
+ pla.getAge());
}
}
6.7.6 static的使用
1.static可用于修饰变量和方法,表示是该类的成员变量或者方法.这些成员时属于整个类的,不属于任何一个类的具体的对象实例,它不保存在某个对象实例的内存区间中,而是保存在类的内存区域的公共存储单元,声明为static的变量实质上就是全局变量不管创建了类的多少实例,整个类中静态变量的副本只有一个。
引用静态变量可以通过引用类的任一实例 ,但是通常我们使用的都是通过类的名称。
与静态方法相关的几个要点:
1)类的静态方法只能访问其他的静态成员
2)静态方法不能被覆盖为非静态方法
3)静态方法没有this
示例:
package com.ambow.c;
public class StaticDemo {
int i=2;
static int a=12;
public static void a(){
//报错:因为静态属于类(公共存储单元【项目】),不属于对象,静态方法中没有this
//this.i=12;
StaticDemo ss=new StaticDemo();
ss.i=12;
ss.a=12;
//报错:因为b方法不是静态方法
// ss.b();
}
public void b(){
StaticDemo ss=new StaticDemo();
//报错:因为a方法不是静态方法
// ss.a();
}
}
2.static静态代码块
语法:
static {
// 语句组
}
功能:完成初始化工作。一般用于软件初始化数据
示例:
package com.ambow.d;
public class StaticBirdDemo {
/*
* static静态代码块 1.作用:初始化工作 2.static静态代码块存在于类中(公共存储单元)
* 3.static静态代码块不管调用或不调用它都随着项目的运行而第一个运行
*/
static {
Bird red = new Bird();
red.setColor("红色小鸟");
red.setHit(80);
red.setAttack(200);
red.display();
}
public static void main(String[] args) {
// Bird bb=new Bird();
}
}