Java面向对象(六)instanceof、类型转换、static、抽象类、接口、内部类
Java面向对象(六)
instanceof和类型转换
instanceof
-
可以判断两个类之间是否存在关系(如父子关系或是否是本身)
-
举例1:
父类:
public class Person { }
子类1:
public class Student extends Person { }
子类2:
public class Teacher extends Person { }
主函数:
public class Application { public static void main(String[] args) { //Person>Student Person s1 = new Student(); Student s2 = new Student(); System.out.println(s1 instanceof Person);//有关系 System.out.println(s2 instanceof Person);//父子关系 System.out.println(s2 instanceof Student);//本身 System.out.println(s1 instanceof Student);//有关系 System.out.println(s1 instanceof Object);//父子关系 //Object>Person>Teacher //Object>Person>Student //Teacher和Student之间没有关系 System.out.println(s1 instanceof Teacher);//没有关系 } } //输出: true true true true true false
注:
System.out.println(s2 instanceof Teacher);//不可以,会报错,因为Student和Teacher是同一级的,没有父子关系
类型转换
-
基本类型的转换:高转低需要强制转换;低转高不需要强制转换
-
父类和子类的转换:
-
高(父)转低(子)需要强制转换;低转高不需要强制转换
-
转换必须保证两个类是有关联的,如父类需要指向子类才能将父类强制转换为子类
-
子类转换为父类会丢失自己本来的方法
-
举例1(强制转换):
父类:
public class Person { public void see(){ System.out.println("看"); } }
子类:
public class Student extends Person { public void say(){ System.out.println("说"); } }
主函数:
public class Application { public static void main(String[] args) { Person obj1 = new Student(); obj1.see(); //将父类强制转换成子类 Student std = (Student) obj1; //强制转换之后就可以调用子类的方法了 //强制转换1 std.say(); std.see(); //强制转换2 ((Student) obj1).say(); } } //输出: 看 说 看 说
-
举例2(低转高,不用强制):
父类:
public class Person { public void see(){ System.out.println("看"); } }
子类:
public class Student extends Person { public void say(){ System.out.println("说"); } }
主函数:
public class Application { public static void main(String[] args) { Student std = new Student(); //子类转父类直接转,不用强制转换 //子类转父类会丢失子类本来的方法 Person obj2 = std; obj2.see(); } } //输出: 看
-
-
类型转换的条件:
- 父类引用指向子类对象;
- 把子类转换为父类,向上转型;
- 把父类转换为子类,向下转型,强制转换;
- 类型转换方便方法的调用,减少重复代码!简洁
static关键字
-
静态方法与属性:
public class Student { private static int age;//静态属性 private double score;//非静态属性 //非静态方法 public void run(){ } //静态方法 public static void go(){ } public static void main(String[] args) { //静态方法使用 go(); //非静态方法使用 Student student = new Student(); student.run(); //静态属性使用(输出) System.out.println(age); //非静态属性使用(输出) Student student2 = new Student(); System.out.println(student2.score); } }
-
匿名代码块、静态代码块、构造方法执行顺序:
- 静态代码块
- 匿名代码块
- 构造方法
public class Person { //匿名代码块 //2.也可以赋初始值 { System.out.println("匿名代码块"); } //静态代码块 //1.只执行一次 static { System.out.println("静态代码块"); } //构造方法 //3 public Person(){ System.out.println("构造方法"); } public static void main(String[] args) { Person person = new Person(); } } //输出: 静态代码块 匿名代码块 构造方法
-
静态导入包:
-
可以直接使用方法
public class Application { public static void main(String[] args) { //Math.random()方法生成随机数 //因为导入的是静态包,所以可以直接用random() System.out.println(random()); } } //输出: 0.5566090462832636
-
-
final:定义常量,一个类被定义成为常量之后就不能被继承;一个量被定义为常量之后就不能像变量一样进行修改
抽象类
-
通过abstract修饰的类是抽象类
-
定义抽象只有方法的名字,没有方法的实现
-
因为抽象类里的抽象方法没有实现过程,所以如果继承带有抽象方法的抽象类的子类不是抽象类的话则子类必须重写抽象方法(为抽象方法写上实现过程)
-
如果继承带有抽象方法的抽象类的子类是抽象类,则不用重写抽象方法(因为抽象类里可以有抽象方法)
-
extends只能实现单继承,但接口可以多继承
-
注意:
- 抽象类不能new,只能靠子类去实现它:约束!(抽象类不能被实例化)
- 只有抽象类里才能有抽象方法
- 抽象类里可以有普通方法,但普通类里不能有抽象方法
-
举例
抽象类:
public abstract class Action { //约束~有人帮我们实现(不用在抽象类里写实现过程) //abstract 抽象方法,只有方法的名字,没有方法的实现 public abstract void doSomething(); }
子类:
//因为抽象类里的抽象方法没有实现过程,所以继承它的类必须重写抽象方法(为抽象方法写上实现过程) public class A extends Action{ @Override //重写抽象方法 public void doSomething() { } }
接口
接口与其它类的区别
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有
- 接口:只有规范-----自己无法写方法~专业的约束!约束和实现分类:面向接口编程
接口与继承的区别
- 类里面有方法的实现
- 接口
接口的本质
- 接口就是一种规范,定义的一组规则。实现“如果是你,必须...”的思想
- 接口的本质是契约,就像我们人间的法律一样,制定好后大家都遵守
接口注意
-
接口只能写方法,不能写方法的实现
-
接口的方法默认都是public抽象的(public abstract)所以public abstract可以不用写,直接写返回值类型和方法的名字就行
-
类通过implements实现接口
-
类可以实现多个接口,接口之间用逗号隔开
-
类实现接口则必须要重写接口里面的所有方法
-
接口中可以定义常量,定义的变量默认是public static final,也就是默认是常量(但一般不会在接口里定义常量)
-
举例:
接口1:
public interface TimeService { void timer(); }
接口2:
public interface UserService { //接口的方法默认都是public抽象的(public abstract)所以public abstract可以不用写,直接写返回值类型和方法的名字就行 void add(String name);//增加 void delete(String name);//删除 void update(String name);//修改 void query(String name);//查询 }
类(实现接口):
//类可以实现接口:implements //实现接口的类必须要实现接口的所有方法 //接口实现多继承 public class UserServiceImpl implements UserService,TimeService{ @Override public void add(String name) { } @Override public void delete(String name) { } @Override public void update(String name) { } @Override public void query(String name) { } @Override public void timer() { } }
接口的作用
- 约束
- 定义一些方法,让不同的人实现~ 例如:10个类共同实现1个接口
- public abstract :接口中默认的方法(抽象方法)
- public static final :静态常量的定义(接口中默认的量都是常量)
- 接口不能被实例化~ 因为接口中没有构造方法~
- implements(接口)可以实现多个(接口之间用逗号隔开)
- 通过implements实现接口必须要重写接口中的方法
内部类
内部类
-
什么是内部类:
在一个类里再写一个类是内部类
-
内部类的功能:
- 内部类可以直接使用外部类的私有变量
-
举例:
类:
public class Outer { private int id=10; public void out(){ System.out.println("这是外部类的方法"); } //内部类 class Inner{ public void in(){ System.out.println("这是内部类的方法"); } public void getID(){ System.out.println(id); } } }
主函数:
public class Application { public static void main(String[] args) { //实例化类 //先实例化外部类 Outer outer = new Outer(); //调用外部类的方法 //外部类无法调用内部类的方法 outer.out(); //只有先实例化外部类才能再通过外部类实例化内部类 //通过外部类实例化内部类 Outer.Inner inner = outer.new Inner(); //调用内部类的方法 //内部类无法调用外部类的方法 inner.in(); inner.getID(); } } //输出: 这是外部类的方法 这是内部类的方法 10
静态内部类
-
public static class 类名:静态内部类
-
静态内部类里的方法不能直接调用外部类的私有的非静态属性。因为静态先产生,非静态后产生,后产生的无法被先产生的先调用
-
举例:
类
public class Outer { private static int id=10; public void out(){ System.out.println("这是外部类的方法"); } //静态内部类 public static class Inner{ public void in(){ System.out.println("这是静态内部类的方法"); } public void getID(){ System.out.println(id); } } }
关于class
-
一个java类中只能有一个public class类,但可以有多个class类
-
举例:
public class Outer2 { } //一个java类中只能有一个public class类,但可以有多个class类 class A{ }
局部内部类
-
写在方法里面的类
-
举例:
public class Outer3 { //局部内部类 public void method(){ class Inner{ public void in(){ System.out.println("这是局部内部类"); } } } }
匿名内部类
-
举例:
public class Application { public static void main(String[] args) { //匿名内部类的使用 new B1().eat(); new B2(){ @Override public void see() { } }; } } class B1{ public void eat(){ System.out.println("内部类1"); } } interface B2{ void see(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理