1.封装
1.1.封装的作用
(1)保证内部结构的安全,外部人员不可随意访问
(2)屏蔽复杂,暴露简单
不封装会使xxx类的属性对外暴露,可以被随意访问、更改,不安全。
1.2.封装方法—private表示私有的,被他修饰后,该数据只能在“当前类”中访问。
封装代码的两步:
(1)、属性私有化(private)
(2)、1个属性对外提供2个set\get方法,可以在set方法中设立关卡(限定传入数据的取值范围,eg.年龄不能为负)保证数据安全
强调:
(1).set、get都是实例方法,不可带static
(2).不带static的方法均是实例方法,调用前必须先new个对象
set长这样:
public void set属性首字母大写 (1个参数){
属性xxx=1个参数;
}
get长这样:
public 返回值类型 get属性首字母大写 (){
return 属性xxx;
}
public class Person
{
private int age;
public void setAge(int nianLing) //实例方法
{
if(nianLing<0 || nianLing>150)//设置关卡,保证数据安全
{
System.out.println("年龄不合法");
return;
}
age=nisanLing;
}
public int getAge()//实例方法
{
return age;
}
}
2.实例方法——依靠对象,不可用static修饰
实例变量、实例方法均依靠对象,调用前必须先new出1个对象。
public class InstanceMethod
{
public static void main(String[] args){
User u =new User();//先new对象
System.out.println(u.iD);//输出:0,系统默认值
u.dosome();//输出:“实例方法执行”
u=null;//切断了风筝线
System.out.println(u.iD);//空指针异常
u.dosome(); //空指针异常
}
}
class User
{
int iD; //实例变量
public void dosome(){
System.out.println("实例方法执行");//实例方法(对象级别的方法)
}
}
3.static
3.1.static修饰的都是“类相关”、“类级别”,永远不会出现空指针异常。
实例(变量、方法),调用前必须先new1个对象,以“引用.”的形式访问
静态(变量、方法),以“类名.”的形式访问
class VarTest{
//实例,调用前必须先new1个对象,以“引用.”的形式访问
int i;//实例变量
public void m1(){ //实例方法
}
//静态,以“类名.”的形式访问
static int k;
public static void m2(){
}
}
3.2.什么时候用static?——所有对象共有的“相同属性”
class 中国人{
int sex;//不同对象基本不同
int age;//不同对象基本不同
static String country = "中国";//所有对象的“相同属性”
}
4.关于空指针异常
结论:只要“空引用”访问“实例”相关,均会有“空指针异常”
class Test
{
public static void main(String[] args){
中国人 p1=new 中国人();
System.out.println(p1.age);//输出:0
System.out.println(p1.country); //输出:中国
//★★★★★★★★★★★★★★
//不建议用这种方法,会让他人误以为country是个实例变量
System.out.println(中国人.country); //输出:中国
//用这种方法,才会让他人认识到country是个静态变量
p1=null;//切断了风筝线
//System.out.println(p1.age);//空指针异常
//★★★★★★★★★★★★★★★★★★★★
System.out.println(p1.country); //仍然正常输出:中国
//因为系统认识到country是个静态变量,
//自动执行了System.out.println(中国人.country);这一句
}
}
class 中国人{
int sex;//不同对象基本不同
int age;//不同对象基本不同
static String country = "中国";//所有对象的“相同属性”
}
5.静态代码块
1.格式
static {
Java 语句;
Java 语句;
Java 语句;
}
2.什么时候执行?
类加载时执行,且只执行一次。
3.它在main方法前执行(在源代码中,无论“静态代码块”处于main之上还是之下)
4.各静态代码块之间一般从上到下执行。
eg.该程序输出结果:
public class StaticTest
{
static{ //静态代码块
System.out.println("a");
}
static{ //静态代码块
System.out.println("b");
}
public static void main(String[] args){
System.out.println("Hello");
}
static{ //静态代码块
System.out.println("c"); //还是先于main方法执行
}
}
6.实例代码块
何时执行?
1.它不在类加载时执行
2.new时,它在构造方法之前执行
如下程序输出结果:
//动态代码块
public class InstanceCodeTest
{
//入口
public static void main(String[] args){
System.out.println("main begin");
new InstanceCodeTest();
new InstanceCodeTest("xyz");
}
public packaging(){
System.out.println("无参数构造");
}
public packaging(String a){
System.out.println("有参数构造");
}
{ //实例语句块,即使在最后,也是先于构造方法执行
System.out.println("实例语句块");
}
}
7.this用法——调用前必须new一个对象
1.this是关键字,全部小写
2.this调用前必须new一个对象
3.它是什么?在内存方面是怎样的?
1个对象1个this。this是一个变量,是一个引用。this保存当前对象的内存地址,并且this自己跟该对象一起存在堆区。
4.this只能使用在实例方法中,谁调用它,this就是谁。
5.this什么时候不可以省略?
在实例方法中或者构造方法中,为了区分局部变量、实例变量,this不可省略
6.如下程序与其内存图:
7. 7.重要例题:
1.定义丈夫类Husband和妻子类Wife
丈夫的属性包括:身份证号 姓名 出生日期 妻子
妻子的属性包括:身份证号 姓名 出生日期 丈夫
2.分别给这两类提供构造方法
创建丈夫对象、妻子对象,并且关联这两个对象
要求能输出——“丈夫对象”的妻子的名字——“妻子对象”的丈夫的名字
3.画出内存图
4.在程序中演示出空指针异常的效果
程序输出结果:
public class Thiso
{
public static void main(String[] args){
Husband h1=new Husband(1234,"张伟","1990-07-01",null);//创建对象并赋值
Wife w1=new Wife(1234,"李丽","1995-10-15",h1);//创建对象并赋值
h1.wife=w1;
System.out.println(h1.name+"的妻子是"+h1.wife.name);
System.out.println(w1.name+"的丈夫是"+w1.husband.name);
}
}
class Husband
{
int iDCard;
String name;
String birth;
Wife wife;
public Husband(){ //无参数构造
}
//有参数构造
public Husband(int iDCard,String name,String birth,Wife wife){
this.iDCard=iDCard;//this在此处用于区分实例变量与局部变量
this.name=name;
this.birth=birth;
this.wife=wife;
}
}
class Wife
{
int iDCard;
String name;
String birth;
Husband husband;
public Wife(){ //无参数构造
}
//有参数构造
public Wife(int iDCard,String name,String birth,Husband husband){
this.iDCard=iDCard;//this在此处用于区分实例变量与局部变量
this.name=name;
this.birth=birth;
this.husband=husband;
}
}
8.this()用法
1.this除了用在实例方法中,还可用在构造方法中
2.新语法:通过当前构造方法去调用另一个位于本类的构造方法
可以用以下语法格式:
this(实际参数列表);//代码复用,此句只能用在该构造方法的第一行!!!!!
class Date{
private int year;
private int month;
private int day;
public Date(){
//System.out.println("无参数构造");//这一句如果不注销,this(1990,7,1)会报错
this(1990,7,1);//只能用在这个构造体中的第一行
}
public Date(int year,int month,int day)
{
this.year=year;
this.month=month;
this.day=day;
}
}
9.重要例题
写一个模拟银行账户
该类包括的属性:账户id,余额balance,年利率rate
包含的方法:各属性set/get的方法。取款方法withdraw(),存款方法deposit()
写一个测试程序
1,创建一个账户Customer,名字叫Jane,他账的账号是1234,余额1000,年利率10%
2.对Jane进行操作:
存入100,再取900,再取2000
打印Jane的基本信息
成功存入:100
成功取出:900
余额不足,取钱失败
程序输出结果:
/*
写一个模拟银行账户
该类包括的属性:账户id,余额balance,年利率rate
包含的方法:各属性set/get的方法。取款方法withdraw(),存款方法deposit()
写一个测试程序
1,创建一个账户Customer,名字叫Jane,他账的账号是1234,余额1000,年利率10%
2.对Jane进行操作:
存入100,再取900,再取2000
打印Jane的基本信息
成功存入:100
成功取出:900
余额不足,取钱失败
*/
public class Account
{
public static void main(String[] args){
//java.util.Scanner s =new java.util.Scanner(System.in);
Custmoer c1=new Custmoer();
c1.setAccountiD(1234);
c1.setName("Jane");
c1.setBalance(1000);
c1.setRate(0.1);
System.out.println(c1.getName()+"的账户"+c1.getAccountiD()+"中余额是:"+c1.getBalance()+",利率是:"+c1.getRate());
//int i=s.nextInt();//存入100
//c1.Deposit(i);
c1.Deposit(100);
//int j=s.nextInt();//取出900
//c1.Withdraw(j);
c1.Withdraw(900);
//int k=s.nextInt();//取出2000
//c1.Withdraw(k);
c1.Withdraw(2000);
}
}
class Custmoer
{
private int AccountiD;//银行账户
private String name;//名字
private int balance;//余额
private double rate;//利率
//银行账户
public void setAccountiD(int accountID)
{
AccountiD=accountID;
}
public int getAccountiD()
{
return AccountiD;
}
//名字
public void setName(String mingzi)
{
name=mingzi;
}
public String getName()
{
return name;
}
//余额
public void setBalance(int yue)
{
balance=yue;
}
public int getBalance()
{
return balance;
}
//利率
public void setRate(double lilu)
{
rate=lilu;
}
public double getRate()
{
return rate;
}
//取钱
public void Withdraw(int money)
{
if(money>0 && money>this.balance)
System.out.println("余额不足,取钱失败");
else if(money>0 && money<this.balance)
{
this.balance-=money;
System.out.println("成功取出:"+money);
System.out.println("账户余额:"+this.balance);
}
else
System.out.println("数额错误");
}
//存钱
public void Deposit(int money)
{
if(money>0)
{
this.balance+=money;
System.out.println("成功存入:"+money);
System.out.println("账户余额:"+this.balance);
}
else
System.out.println("数额错误");
}
}
10.实例变量、静态变量、局部变量——区分