Final关键字
package demo07;
public class Demo02Final {
/*day11【final、权限、内部类、引用类型】
* 学习了继承之后,子类可以对父类的方法进行重写,那么能不能对API中的文档进行随意的改写呢?
* 答案显然是否定的,为了避免这种情况,JAVA提供了final关键字,用于修饰不可改变的内容
* final:不可改变,可以修饰类、方法、变量
* 怎么体现:被修饰的类,不可以被继承
* 被修饰的方法,不可以被重写
* 被修饰的变量,不可以被重新赋值*/
}
先对a进行final修饰
package demo07;
public class Demo01Final {
public static void main(String[] args) {
final int a = 0;
// a = 10;
/*Cannot assign a value to final variable a*/
}
}
权限修饰符
在Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,
public:公共的
protected:受保护的
default:默认的
private:私有的
public protected default(空的) private
同一类中 √ √ √ √
同一包中(子类与无关类) √ √ √
不同包的子类 √ √
不同包中的无关类 √
可见,public具有最大权限。private则是最小权限。
编写代码时,如果没有特殊的考虑,建议这样使用权限:
成员变量使用private ,隐藏细节。
构造方法使用public ,方便创建对象。
成员方法使用public ,方便调用方法。
小贴士:不加权限修饰符,其访问能力与default修饰符相同
匿名内部类就是省略了实现了类的书写,在定义测试类的时候,直接重写接口中的抽象方法
1.不使用匿名内部类
1.1 定义接口
package demo08;
public interface MyInterface {
void method(); //抽象方法,省略了public abstract
/*有没有一眼就能看出是抽象方法的本事?没有{}*/
}
1.2 定义实现类
package demo08;
public class MyInterfaceImpl implements MyInterface {
/*覆盖重写,alt + enter,implements interface*/
@Override
public void method() {
System.out.println("实现类覆盖重写了方法!");
}
}
1.3 定义测试类
package demo08;
public class DemoMain {
/*实现接口*/
public static void main(String[] args) {
/*左父右子,实现多态*/
MyInterface impl = new MyInterfaceImpl();
impl.method();
}
2.使用匿名内部类
2.1定义接口
package demo08;
public interface MyInterface {
void method(); //抽象方法,省略了public abstract
/*有没有一眼就能看出是抽象方法的本事?没有{}*/
}
2.2定义测试类的时候使用匿名内部类重写接口中的抽象方法
package demo08;
public class DemoMain {
/*实现接口*/
public static void main(String[] args) {
/*如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,就可以使用匿名内部类
*
* 定义格式:
* 接口名称 对象名 = new 接口名称(){
* //覆盖重写接口中所有的抽象方法
* };
* 大括号里面就是内部类的内容*/
//局部内部类 这个类没有名字的,所以叫匿名内部类,比之前节省了一个实现类的书写,方便了许多
MyInterface obj = new MyInterface() {
@Override
public void method() {
System.out.println("实现了匿名内部类!");
}
}; //这里的分号不能丢
//对象名称叫obj
obj.method();
}
}
new 接口名称(){...}进行解析:
1.new代表创建对象的动作
2.接口名称就是匿名内部类需要实现哪个接口
3.{...}才是匿名内部类的内容
另外还要注意几点问题:
用了一次就不用第二次的可以使用匿名内部类但是创建对象obj之后只能使用唯一一次
3 class作为成员变量需要的实现,可以帮助理解set()和get()方法
3.1定义一个英雄类,想把武器类作为引用类型放到英雄类里面去
3.1.1 定义一个Hero类
引用类型Weapon,添加了一个打人的方法进去
package demo10;
/*类可以当做成员变量么?*/
public class Hero {
private String name; //英雄名字
/*这里的String是什么呢?
* 通过Ctrl键进行查看,发现是一个Class,也就是说Class是可以充当成员变量的*/
private int age;
private Weapon weapon; //武器
public Hero() {
}
public Hero(String name, int age, Weapon weapon) {
this.name = name;
this.age = age;
this.weapon = weapon;
}
//定义一个打人的方法
public void attack(){
System.out.println("年龄为" + age + "的" + name + "用"+ weapon.getCode()+"攻击敌方");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Weapon getWeapon() {
return weapon;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
}
3.2定义weapon类想把这个类当做成员变量放到Hero类中去
package demo10;
public class Weapon {
/*想把这个类当做成员变量放到Hero类中去*/
private String code; //武器的代号
public Weapon() {
}
public Weapon(String code) {
this.code = code;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
3.3实例
package demo10;
public class DemoMain {
public static void main(String[] args) {
//创建一个英雄角色
Hero hero = new Hero();
hero.setName("盖伦");
hero.setAge(20);
//创建一个武器对象
Weapon weapon = new Weapon("多兰剑");
//为英雄配备武器
hero.setWeapon(weapon);
hero.attack();//就是一个显示的功能
}
}
class可以作为成员变量,那么,接口interface是否也可以作为成员变量呢?
什么是接口?接口是对方法的封装,相当于是在对英雄的技能进行扩充,可以在Hero中,增加接口作为成员变量来设置不同的技能。
toString
重写toString方法使其打印属性
package demo12;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/*Person默认继承了Object类*/
@Override/*重写toSting*/
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
package demo12;
public class ToString {
public static void main(String[] args) {
Person p = new Person();
String s = p.toString();
System.out.println(s);/*5f184fc6十六进制的地址值*/
/*直接打印对象的名字,其实就是调用toString方法*/
/*打印地址值是没有意义的,重写toString方法打印属性*/
}
}
包装类:对象可以做更多的事情,如果想把基本类型变得像对象一样操作,可以把基本类型变成包装类。
基本类型 | 对应的包装类(位于java.lang包中) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
那么基本类型和对应的包装类之间怎么进行变换么?
装箱与拆箱
装箱:从基本类型转换为对应的包装类对象
拆箱:从包装类对象转换为对应的基本类型
包装类就是把什么东西给装起来,把什么装起来呢,把类给装起来,可以使用一个类把基本类型的数据装起来,这个类就叫做包装类,我们可以使用类中的方法去操作这些基本类型的数据。
package demo13;
import java.util.ArrayList;
public class Demo01Integer {
public static void main(String[] args) {
Integer in1 = new Integer(1);
System.out.println(in1);//new一个对象打印出来一个1,证明重写了toSting方法
/*看到左边只有Integer右边就一个数字,就是自动装箱*/
ArrayList<Integer> list = new ArrayList<>();
/*ArrayList集合无法直接存储整数,但是可以存储Integer包装类*/
list.add(1);
Integer integer = list.get(0);
System.out.println(integer.intValue());
}
}
基本类型和字符串类型的转化