final关键字+四种权限修饰符+内部类

final

  • 不可改变的
  • 修饰类,该类不能拥有子类
  • 修饰方法,父类方法有final修饰,子类不能覆盖重写
  • 局部变量不能改变
  • 引用对象,地址值不能改变,不能new新的对象重新赋值,但可以改变里面的内容
public class FinalDemo2 {
public static void main(String[] args) {
// 创建 User 对象
	final User u = new User();
// 创建 另一个 User对象
	u = new User(); // 报错,指向了新的对象,地址值改变。
// 调用setName方法
	u.setName("张三"); // 可以修改
}
}

如果成员变量是final类型,只能使用以下的两种方法进行赋值

  • 直接赋值
public class User {
	final String USERNAME = "张三";
	private int age;
}
  • 使用setter赋值
public class User {
	final String USERNAME ;
	private int age;
	public User(String username, int age) {
	this.USERNAME = username;
	this.age = age;
}
}

四种权限修饰符

public>protected>(default)不写>private
在这里插入图片描述

内部类

应用场景

  • 身体和心脏的关系,汽车和发动机的关系(把心脏,发动机拿出来都没用)

  • 成员内部类

  • 局部内部类,不能使用权限修饰符

//外部类
public class Body {
//成员内部类
	public class Heart{
	//内部类方法
	public void beat(){
		System.out.println("心脏跳动");
		//可访问外面的
		System.out.println("我叫"+name);
}
	}
	//外部类变量
	private String name;
	//外部类方法
	public void methodBody(){
	//局部内部类,前面不能使用过任何修饰
	class Inner
	{
	int num=10;
}
		System.out.println("外部类的方法");
		//间接使用内部类的方法
		new Heart().beat();
}
}
}

使用成员内部类

  • 间接调用
public class FinalDemo2 {
public static void main(String[] args) {
	Body body=new Body();
	//外部方法间接调用内部方法
	body.methodBody();
}
}
  • 直接调用
public class FinalDemo2 {
public static void main(String[] args) {
	//创建内部类对象,直接调用内部类的方法
	//外.内 对象名=new wai().nei()
	Body.Heart heart=new Body().new Heart();
	heart.beat();
}
}

匿名内部类

接口的实现类,只需要使用唯一的一次的时候,使用匿名内部类
接口

public abstract interface FlyAble{
	 void fly();
}

使用内部类

public class InnerDemo {
public static void main(String[] args) {
/*
1.等号右边:是匿名内部类,定义并创建该接口的子类对象
2.等号左边:是多态赋值,接口类型引用指向子类对象
*/
//匿名内部类,覆盖重写接口的方法,可以采用补充方法的方式, 直接使用接口
	FlyAble f = new FlyAble(){
	@override
	 void fly() {
	System.out.println("我飞了~~~");
}
};
//调用 fly方法,执行重写后的方法
	f.fly();
	//匿名对象
	 new FlyAble(){
	@override
	 void fly() {
	System.out.println("我飞了~~~");
}.fly();
}
}

自定义的类作为成员变量类型

定义武器类

class Weapon {
String name; // 武器名称
int hurt; // 伤害值
}

角色类中里面有武器类

class Role {
	int id;
	int blood;
	String name;
// 添加武器属性
	Weapon wp;
// 添加盔甲属性
	Armour ar;
// 提供get/set方法
public Weapon getWp() {
	return wp;
}
public void setWeapon(Weapon wp) {
	this.wp = wp;
}
public Armour getArmour() {
	return ar;
}
public void setArmour(Armour ar) {
	this.ar = ar;
}

测试类

public class Test {
public static void main(String[] args) {
// 创建Weapon 对象,武器是一个类,要创建一个对象
	Weapon wp = new Weapon("屠龙刀" , 999999);
// 创建Armour 对象,是一个类,要创建一个对象
	Armour ar = new Armour("麒麟甲",10000);
// 创建Role 对象
	Role r = new Role();
// 设置武器属性
	r.setWeapon(wp);
// 设置盔甲属性
	r.setArmour(ar);
// 攻击
	r.attack();
// 穿戴盔甲
	r.wear();
}
}

interface作为成员变量

定义攻击接口

// 法术攻击
public interface Skill {
	public abstract void use();
}

实现攻击

public class SkillIMPL implements Skill {
	@override
	public void use(){
	System.out.println("Biu~Biu");
}
}

定义英雄类

	public class Hero{
	private String name;
	private Skill skill;
	public Hero(){}
	public Hero(String name,Skill skill)
	{
	this.name=name;
	this.skill=skill;
}

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

	public Skill getSkill()
{
	return skill;
}
	public void setSkill(Skill skill)
{
	this.skill=skill;
}

public void attack(){
	System.out.println("我叫"+name+"开始释放技能");
	//父类(接口),子类都有同名函数,优先使用子类的use(),类比前面学的电脑usb接口的程序
	skill.use();
	System.out.println("技能释放完成");
}
}

测试类
有三种方法实现skill

  • 直接创建新的skill对象
  • 创建匿名内部类

public class Test {
public static void main(String[] args) {
	Hero hero=new Hero();
	hero.setName("aaa");
	//向上转型,类比前面学的电脑usb接口的程序
	hero.setSkill(new SkillIMPL());
	hero.attack();
	//创建匿名内部类,直接补充skill里的内容,并赋值到到skill对象里面
	Skill skill=new Skill(){
	@override
	public void use(){
	System.out.println("pia-pia");
};
	hero.setSkill(skill);
}
	hero.attack();
//补充创建skill对象,直接使用匿名对象,只能使用一次
	hero.setSkill(new Skill){
	@override
	public void use(){
	System.out.println("pia-pia");
	hero.attack();
}
}
}
}

接口作为方法的参数和返回值

其中list是ArrayList的接口

public class DemoInterface{
	public  static void main(String[] args){
	//该用法为多态里面的用法
	List<String> list=new ArrayList<>();
	List<String> result=addNames(list);
	for(int i=0;i<result.size();i++)
	{
	System.out.println(result.get(i));
}
}
}

//addNames函数
//接口作为方法的参数和返回值
public static List<String> addNames(List<String> list)
{
	list.add("a");
	list.add("b");
	list.add("c");
	return list;
}

更加高级的发红包案例

  • 所有人都有红包,大家抢完之后,最后一个红包给群主自己
    利用现成的代码,还需要补充的地方有三个

  • 设置图形界面标题,就是MyRed利用传参构造函数

  • 设置群主名称,利用setter

  • 设置分发策略,平均or随机

public class Bootstrap{
	public static void main(String[] args)
	{
	//不能直接new接口(抽象类),要使用实现MYRED
	//RedPacketFrame frame=new RedPacketFrame();
	//使用子类(实现类),接口中只有有参构造方法,要使用有参构造方法
	MyRed red=new MyRed("新年红包");
	//设置群主名称
	red.setOwnerName("aaa");
	//设置红包怎么分的方法
	//普通红包
	OpenMode normal=new NormalMode();
	red.setOpenWay(normal);
	//手气红包
	OpenMode random=new RandomMode();
	red.setOpenWay(random);
	
}

}

接口

public interface OpenMode {
    /**
     * 请将totalMoney分成count份,保存到ArrayList<Integer>中,返回即可。
     *
     * @param totalMoney            总金额为方便计算,已经转换为整数,单位为分。
     * @param totalCount            红包个数
     * @return ArrayList<Integer>	元素为各个红包的金额值,所有元素的值累和等于总金额。
     */
    ArrayList<Integer> divide(int totalMoney, int totalCount);
}

普通平均红包的方法

public class NormalMode implements OpenMode {
    @Override
    public ArrayList<Integer> divide(final int totalMoney, final int totalCount) {
        ArrayList<Integer> list = new ArrayList<>();

        int avg = totalMoney / totalCount; // 平均值
        int mod = totalMoney % totalCount; // 余数,模,零头

        // 注意totalCount - 1代表,最后一个先留着
        for (int i = 0; i < totalCount - 1; i++) {
            list.add(avg);
        }

        // 有零头,需要放在最后一个红包当中
        list.add(avg + mod);

        return list;
    }
}

随机手气红包

public class RandomMode implements OpenMode {
    @Override
    public ArrayList<Integer> divide(final int totalMoney, final int totalCount) {
        ArrayList<Integer> list = new ArrayList<>();

        // 随机分配,有可能多,有可能少。
        // 最少1分钱,最多不超过“剩下金额平均数的2倍”
        // 第一次发红包,随机范围是0.01元~6.66元
        // 第一次发完之后,剩下的至少是3.34元。
        // 此时还需要再发2个红包
        // 此时的再发范围应该是0.01元~3.34元(取不到右边,剩下0.01)

        // 总结一下,范围的【公式】是:1 + random.nextInt(leftMoney / leftCount * 2);
        Random r = new Random(); // 首先创建一个随机数生成器
        // totalMoney是总金额,totalCount是总份数,不变
        // 额外定义两个变量,分别代表剩下多少钱,剩下多少份
        int leftMoney = totalMoney;
        int leftCount = totalCount;

        // 随机发前n-1个,最后一个不需要随机
        for (int i = 0; i < totalCount - 1; i++) {
            // 按照公式生成随机金额
            int money = r.nextInt(leftMoney / leftCount * 2) + 1;
            list.add(money); // 将一个随机红包放入集合
            leftMoney -= money; // 剩下的金额越发越少
            leftCount--; // 剩下还应该再发的红包个数,递减
        }

        // 最后一个红包不需要随机,直接放进去就得了
        list.add(leftMoney);

        return list;
    }
}

图形界面的实现类

public class MyRed extends RedPacketFrame {
    /**
     * 构造方法:生成红包界面。
     *
     * @param title 界面的标题
     */
    public MyRed(String title) {
        super(title);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值