private和final的讲解以及一些例子

private–只能被本类使用

##为什么要使用private
1.为了程序更好的封装性(但程序的封装性取决很多方面,private只是其中之一),使类的成员变量不会被外界随意修改。for safety from rep exposure(防止泄露),我们应该给成员变量使用private修饰符,然后通过set,get方法去获取和赋值成员变量
2.因为private而产生的set,get方法里可以对外界输入的变量的值进行判定是否合乎我们的规范,用if语句判断(if语句可不能用在方法体外,所以没有set方法可不能对输入进行限定)。
##用了private后如何新建自带属性的引用数据类型
例如棋牌游戏中有个类Player(玩家类),需要给玩家一个名字作为玩家的唯一标识。同时在game(游戏类)新建玩家,并初始化玩家(即给玩家名字)那这一系列操作如何实现?下面从构造方法的不同角度给出两种方案。

**#类中没有带参的构造方法,**Java会自动给你生成一个不带参的构造方法1.
1.首先在Player类中成员变量定义区定义name变量。

private String name;

name为private的了,game要访问name只能通过player类的get,set方法了。
2.在Player里写getName,setName方法(注意方法名的书写规范,在编译器里是会帮助你的书写)

public String getName() {
    return name;
}
public void setName(String name){
    this.name = name;
}

3.在game类新建Player对象,一般为了防止后面访问出现空指针异常(这是Java程序中常见的错误),会直接new出来,而且是无参的构造函数,不带name。

Player player = new Player();

这时给了Player对象一个堆内存的地址,Player对象不为空。
4.在game类里写initplayer方法,方便main函数里去调用game.initplayer方法去初始化玩家对象。initplayer方法里调用player.setName方法。这样就给玩家赋予了名字

public void initplayer(String name) {
    player.setName(name);
}

#类里有带参的构造函数,Java就不会自动生产无参的构造方法了,如果需要请自行生成。
1.带参的构造方法,new的时候就要传入参数name,但是人的名字千变万化,怎么能给一个固定的名字呢?
2.我们可以随便先给一个无意义的名字。然后在别的类要传入真正的名字时,再调用的方法setName。

Player player = new Player("001");
player.setName("Rose");

这样也给玩家赋予了名字。
##用了private后如何去获取成员变量
使用get方法即可,同样如上例。我们需要在game类定义private的Player对象,但在Game的子类也需要访问到这个Player对象,那么应该怎么办?
1.在game类里写getPlayer方法。

public Player getplayer() {
    return this.player;
}

2.在game的子类chessgame里需要调用这个Player对象方法时如下操作,注意我们只会在子类用get方法时用到this,表示当前对象。在别的不相干的类里,都是new一个player对象(比如 p)然后p.getPlayer.addpiece.

this.getplayer().addpiece(WKing);

final–已初始化的变量不能再指向另外的值/对象

final基本知识点
(1)修饰类的时候此类不能被继承。
(2)修饰方法时方法不能被重写。
(3)c修饰变量时不能被重新赋值。
##为什么用final
如同private,为了程序更好的安全性,让外界不能任意修改我们的变量,所以for safety from rep exposure(防止泄露),我们也应该尽量使用final修饰符。但要明确知道这个不能修改我们的变量是不能修改什么!
##不能修改的是引用(地址),而不是地址所指向的内容
有个问题,为什么 final String a = “jack”,这个 a 就不能再 a = “rose”;但 final Map map,final List list后我们还可以进行map.put,list.put等方法调用。这就涉及到final改变的到底是什么的问题。

  1. final的意思是一个已初始化的变量不能再指向另外的值/对象。意思是地址(引用)不可变,但地址指向的内容可以变。
  2. 对Map, list的add, put等操作没有修改map, list的引用,只是修改了引用指向的内容,所以可以用map,list提供的方法。
  3. 对于实例变量,一旦New一个对象,就为这个对象分配了内存地址。
    如:final Person p = new Person(“张三”);
    (1) p不能改地址:p = new ArrayList();//报错
    (2) 若person类里,name为private属性,p.name = “王五”;//报错
    正解:Person里写一个setName方法,调用p.setName(“王五”);p的地址没有变。
  4. String没有提供修改属性的方法,假设一下:
    b.setValue(“修改String的值”);//正确
    可是实际情况是:String没有提供任何修改自身值的方法,他是一个不可变类,每次重新给String赋值,都是新建一个String对象(地址也变了),这样来改变String的值。注意:final修饰基本类型时,基本类型的值都不能改变,因为Java中基本类型都没有提供任何修改自身值的方法,每次赋予新值都是创建一个新对象。

所以为了安全尽量用final,但用之前想清楚我们有没有需求需要在类里一些地方new 对象,若有则不能用。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值