1、abstract
abstract使用注意事项:
- abstract修饰属类和方法
- abstract不能修饰属性,构造方法,私有方法,静态方法,final方法,final类
- abstract修饰类:抽象类–>不能实例化;抽象类中一定有构造方法,便于子类实例化使用,开发中都会提供抽象类的子类,让子类对象实例化,完成相关操作。
- abstract修饰方法:抽象方法只有方法体,
2、 匿名对象
匿名就是没有名字的对象,在创建对象时,只通过new的动作在堆内存开辟空间,却没有把堆内存空间的地址值赋值给栈内存的某个变量用以存储
class Student{
String name;
public Student(){
this.name = "无";
System.out.println("你调用了一次无参构造函数");
}
public Student(String name){
this.name = name;
System.out.println("你调用了一次有参构造函数");
}
public void setName(String name){
System.out.println("你改名了");
this.name = name;
}
public void show(){
System.out.println("名字是:" + name);
}
}
public class AnonymityTest {
public static void main(String[] args) {
//有名字的对象
Student s = new Student();
s.show();
System.out.println("---------------");
//匿名对象,匿名对象只能使用一次,如下实际创建了五个匿名对象
new Student();
System.out.println("---------------");
new Student().show();
System.out.println("---------------");
new Student("张三");
System.out.println("---------------");
new Student("lisa").show();
System.out.println("---------------");
new Student().setName("Tom");
}
}
输出:
你调用了一次无参构造函数
名字是:无
---------------
你调用了一次无参构造函数
---------------
你调用了一次无参构造函数
名字是:无
---------------
你调用了一次有参构造函数
---------------
你调用了一次有参构造函数
名字是:lisa
---------------
你调用了一次无参构造函数
你改名了
Process finished with exit code 0
在内存中的示意图:
-
new Student() 在堆内存开辟空间,同时产生一个地址值,我们在这里以0x11表示,实际的地址值不是这个,是一个更复杂的组合方式;将栈内存创建一个引用变量s,将该地址值赋值给s,这时就可以通过s访问堆内存空间的对象,这个s就是对象的名字,这个对象就叫做有名字的对象。
相对应的,如果s不存在的话,就是匿名对象。 -
匿名对象特点:
1、由于我们没有记录堆内存对象的地址值,所以只能用一次,再次使用就找不到了
2、匿名对象的好处就是使用完毕就是垃圾,可以在垃圾回收器空闲时回收,节省内存空间 -
匿名对象其实就是对象,对象具有的功能匿名对象都具有,只不过有名字的对象可以重复使用,匿名对象只能用一次罢了。
3、抽象类的匿名子类对象
abstract class Creature{
public Creature(){
};
abstract public void eat();
abstract public void breath();
}
class person extends Creature{
@Override
public void eat() {
System.out.println("人要多吃东西");
}
@Override
public void breath() {
System.out.println("人要多呼吸新鲜空气");
}
}
class cat extends Creature {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void breath() {
System.out.println("猫呼吸空气");
}
}
public class AnonymityTest {
public static void method1(Creature p){
p.eat();
p.breath();
}
public static void method2(cat c){
c.breath();
c.eat();
}
public static void main(String[] args) {
method1(new person());//匿名对象------人要多吃东西 人要多呼吸新鲜空气
cat c = new cat();
method2(c);//非匿名类,非匿名对象--------猫呼吸空气 猫吃鱼
method1(new cat());//非匿名类匿名对象-----猫吃鱼 猫呼吸空气
//创建了一个匿名子类的有名对象,子类无名
Creature cr = new Creature() {
@Override
public void eat() {
System.out.println("老八吃粑粑");
}
@Override
public void breath() {
System.out.println("窒息死亡");
}
};
method1(cr);//老八吃粑粑 窒息死亡
//创建匿名子类的匿名对象
method1(new Creature() {
@Override
public void eat() {
System.out.println("吃好吃的");
}
@Override
public void breath() {
System.out.println("缺氧");
}
});//吃好吃的 缺氧
}
}
4、接口
4.1接口体中包含常量的声明(没有变量)和抽象方法两部分。
- 接口体中只有抽象方法,没有普通的方法。
- 接口体中所有的常量的访问权限一定都是public,而且是static常量(允许省略public,final和static修饰符),所有的抽象方法的访问权限一定都是public(允许省略public abstract修饰符)。
例如:
interface printable{
public static final int MAX = 100//等价写法: int MAX = 100
public abstract void add();//等价写法:void add();
public abstract float sum(float x, float y);
}
4.2重写接口中的方法
如果一个非抽象类实现了某个接口,那么这个类必须重写这个接口中的所有方法。需要注意的是,由于接口中的方法一定是public abstract方法,2以类在重写接口方法时不仅要去掉abstract修饰符,给出方法体,而且方法的访问权限一定要明显地使用public来修饰(否则降低了权限,这是不允许的)。实现接口的非抽象类实现了该接口中的方法,及给出了方法的具体行为。
4.3接口回调
接口回调是指:可以把实现某一接口的类创建的对象的引用赋值给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口方法。实际上,当接口变量调用被类实现的接口方法时,就是通知相应的对象调用这个方法。