关于面向对象
关于面向对象还有instanceof, static的解释,抽象类还有接口方面的点,再回顾总结一下。
instanceof和类型转换
instanof
instanceof是看两个对象有没有继承关系的,有就是true 没有就是flase。
boolean result = obj instanceof Class
在这里obj必须是一个引用类型,如果obj为Class的直接或间接子类,那么就返回true,在这里instanceof实际上就是一个双目运算符
先创建一个父类
public class Person {
}
子类
public class Student extends Person{
}
测试:
Student student = new Student();
Person person = new Person();
Person p = new Student();
System.out.println(student instanceof Person); //true
System.out.println(p instanceof Student); //true
System.out.println(p instanceof Person); //true
System.out.println(person instanceof Student); //false
这里person是Person类,不继承于Student类所以为false
类型转换
和基本类型的强制转换差不多,低转高自动转换,高转低需要强制转换
这里就是父类转子类需要强制转换了
//比如这里Student类里有个text()方法,父类对象要使用这个方法
Person person = new Student();
((Student) person).text();
这样就能够进行强制转换从而让person可以调用Student的方法了
类型转换注意点
- 父类引用指向子类对象
- 把子类转成父类,向上转型
- 父类转子类,向下转型 :强制转换
- 减少重复代码,提高利用率
static
其实static接触的很早,比如经典的psvm
非静态方法可以访问所有静态方法,而静态方法则不能通过类名去访问非静态方法,要实例化一个对象才能够访问。
因为static方法是和类一起加载的,它们加载好的时候,那些非静态方法还没有加载,要通过实例化对象,加载那些非静态方法,才可以访问
静态/匿名代码块
我们在new一个对象的时候,构造器总是在最前面,实际上还有两个东西,叫匿名代码块和静态代码块,这两个都是先于构造器加载完毕,然后静态代码块是只会执行一次,下面放一个示例代码看看匿名静态代码块吧
public class Student {
{
System.out.println("匿名代码块执行了");
}
static {
System.out.println("静态代码块执行了");
}
public Student() {
System.out.println("构造方法执行了");
}
public static void main(String[] args) {
System.out.println("=================");
Student student = new Student();
System.out.println("=================");
Student student1 = new Student();
}
}
// 系统输出结果
// 静态代码块执行了
// =================
// 匿名代码块执行了
// 构造方法执行了
// =================
// 匿名代码块执行了
// 构造方法执行了
可以看到最先执行静态代码块,并且只会执行一次,然后匿名代码块和构造器都是每new一下执行一次,匿名代码块在构造方法前执行
静态导入包
import static java.lang.Math.random;
public class Application {
public static void main(String[] args) {
System.out.println(random());
}
}
导包的时候加上static,就可以把java.lang包下的Math方法直接导进去,这样我们使用random方法都不需要写Math类再去使用random方法,直接写就完事了
抽象类
通过abstract修饰符来定义一个抽象类,abstract也可以修饰方法,来定义一个抽象方法,但是抽象方法必须放在抽象类里
创建一个抽象类,里面创建一个抽象方法
public abstract class Action {
//抽象方法只有名字,没有方法 必须放在抽象类里
public abstract void doSomeThing();
//可以写普通方法
public void do(){
}
}
创建子类继承这个Action
public class A extends Action{
}
这时候编译器会显示报错啊
是因为继承抽象类时,抽象类里面的所有方法都必须重写,如下
public class A extends Action{
@Override
public void doSomeThing() {
}
}
除非继承它子类也是一个抽象类,这样就不用重写方法了
另外,抽象类是不能够被实例化的,只能靠子类去实现它
到这就对抽象类有一个认识了
- 抽象类不能够被new出来,只能靠子类去实现
- 抽象方法必须在抽象类里
- 抽象类里可以写普通方法
接口
接口只有规范,自己不能写方法,只有约束,专业的。
接口的本质是契约,制定好后都去遵守
定义:接口使用interface定义
public interface UserService {
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
接口中所有的定义都是抽象的 public abstract
接口都需要一个实现类
类可以实现接口,关键字 implements
抽象类的实现靠子类 :extend ,这是单继承的
接口实现靠implements ,和extend不一样,这个可以多继承,一个类可以继承多个接口
public class UserServiceImpl implements UserService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
}
当然因为接口里的方法都是默认抽象,因此实现类就必然要重写接口里的方法了
关于接口
- 接口定义一些方法,然后让不同的类去实现
- 默认方法public abstract
- 默认属性public static final , 它定义的属性都默认静态常量
- 接口不能被实例化,也没有构造器
- 实现类关键字implements, implements可以让一个实现类继承多个接口
- 接口的实现类必须重写接口的方法