面向对象
面向对象
OOP的本质:以类的方式组织代码,以对象的防止组织(封装)数据
三大特性
-
封装
-
保护数据、隐藏代码细节、属性私有set/get
-
alt+insert:自动生成get、set方法
-
-
继承
-
java类只有单继承,接口有多继承
-
final修饰后不能被继承
-
ctrl+h显示继承树
-
super
-
//父类
//所有的类都直接或间接继承Object类,ctrl+h查看
class Person {
protected String name = "wmj";
public Person() {
System.out.println("person的无参构造函数");
}
public void print() {
System.out.println("person");
}
}
//子类
class Student extends Person {
private String name = "ww";
public Student() {
//隐藏代码 调用了父类的无参构造函数
super();//调用父类的构造器必须放在第一行
System.out.println("student的无参构造函数执行了");
}
public Student(String name) {
this.name = name;
}
public void print() {
System.out.println("student");
}
public void test(String name) {
System.out.println(name);//hhh
System.out.println(this.name);///ww
System.out.println(super.name);//wmj
}
}
//测试
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("hhh");
}
}
/*
person的无参构造函数
student的无参构造函数执行了
haha
ww
wmj
*/
方法重写(只和非静态方法有关)
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大不可缩小:public>protected>default>private
- 抛出的异常:范围,可以缩小不能扩大
- 静态方法
class B {
public static void test() {
System.out.println("B.test()");
}
}
class A extends B {
public static void test() {
System.out.println("A.test()");
}
}
public class Application {
public static void main(String[] args) {
//方法的调用只和左边的数据类型有关
A a = new A();
a.test();//A.test()
//父类的引用指向了子类
B b = new A();
b.test();//B.test()
}
}
- 非静态方法
class B {
public void test() {
System.out.println("B.test()");
}
}
class A extends B {
@Override
public void test() {
System.out.println("A.test()");
}
}
public class Application {
public static void main(String[] args) {
//方法的调用只和左边的数据类型有关
A a = new A();
a.test();//A.test()
//父类的引用指向了子类
B b = new A();
b.test();//A.test()
}
}
- 多态
-
同一方法可以根据发送对象的不同而采用多种不同的行为方式
-
多态是方法的多态
-
父类和子类有联系 类型转换异常:ClassCastException!
-
存在条件:继承关系、方法要重写、父类引用指向子类对象!
-
static属于类,final在常量池,private方法都不能重写
-
//所有的类都直接或间接继承Object类,ctrl+h查看
class Person {
public void run() {
System.out.println("person");
}
}
class Student extends Person {
@Override
public void run() {
System.out.println("student");
}
public void eat() {
System.out.println("eat");
}
}
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//可以指向的引用类型就不确定了 父类的引用指向子类
//Student 能调用的方法都是自己的或者继承父类的
Student s1 = new Student();
//Person 不能调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
s1.run();//student 子类重写了父类的方法,执行子类的方法
s2.run();//student
//对象能执行那些方法,主要看左边的类型
//s2.eat();错
((Student) s2).eat();
s1.eat();
}
}
instance
public class Application {
public static void main(String[] args) {
//System.out.println(x instanceof y);能否编译通过取决于是否有父子关系
//xy是同一级别会编译报错
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object object1 = new Student();
System.out.println(object1 instanceof Student);//true
System.out.println(object1 instanceof Person);//true
System.out.println(object1 instanceof Object);//true
System.out.println(object1 instanceof Teacher);//false
System.out.println(object1 instanceof String);//false
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Object);//true
System.out.println(person instanceof Teacher);//false
//System.out.println(object2 instanceof String);编译报错
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
//System.out.println(student instanceof Teacher);编译报错
//System.out.println(student instanceof String);编译报错
}
}
-
父转子要强制转换,才能使用子类特有方法,丢失父类子自己的那个被子类重写的方法
-
子转父,会丢失子类特有方法
//所有的类都直接或间接继承Object类,ctrl+h查看
class Person {
public void run() {
System.out.println("person run");
}
}
class Student extends Person {
@Override
public void run() {
System.out.println("strdent run");
}
public void go() {
System.out.println("go");
}
}
public class Application {
public static void main(String[] args) {
//父转子
Person student1 = new Student();
//student1.go();父类不能调用子类独有的方法,转换成子类的类型才行
((Student) student1).go();//强制类型转换
((Student) student1).run();//strdent run 丢失父类子自己的那个被子类重写的方法
//子转父
Student student2 = new Student();
student2.go();
Person person = student2;
//person.go();子类转父类丢失子类特有的方法
}
}
static
class Student extends Person {
//执行顺序
//第2.赋初始值
{
System.out.println("匿名代码块");
}
//第1.只执行一次
static {
System.out.println("静态代代码块");
}
//第3.
public Student() {
System.out.println("构造函数");
}
//执行顺序
//静态代代码块
//匿名代码块
//构造函数
}
// import static java.lang.Math.random;
// 静态导入包 Math.random -> random
public class Application {
public static void main(String[] args) {
Student student = new Student();
}
}
抽象类
public abstract class Action {
//不能new出来,只能靠子类去继承
//让子类去实现抽象方法,除非他的子类也是抽象类
//抽象方法只能在抽象类里
public abstract void doSomething();
//可以写普通的方法
public void fun() {
System.out.println("ttt");
}
}
-
构造器
抽象类的构造函数用来初始化抽象类的一些字段,而这一切都在抽象类的派生类实例化之前发生,可以在其内部实现子类必须执行的代码
接口
public interface UserService {
//没有构造方法
//常量都是public static final
int AGE = 0;
//接口中定义的方法都是抽象的public
void add(); // public abstract
void delete();
void update();
void query();
}
public interface TimeService {
void timer();
}
//利用接口实现多继承
public class UserServiceImpl implements UserService, TimeService {
//实现了接口的类必须重写接口中的所有方法
@Override
public void delete() {
}
@Override
public void update() {
}
@Override
public void query() {
}
@Override
public void add() {
}
@Override
public void timer() {
}
}
内部类
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 void method() {
class Inner2 {
}
}
}
// 静态内部类:不需要依赖于外部类,和类的静态成员属性类似,并且它不能使用外部类的非static成员变量或者方法
static class Inner2 {
}
}
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// 获得外部类的私有属性
inner.getID();
new Outer().out();
// 匿名内部类,不用把实例保存到变量中
new UserService() {
@Override
public void hello() {
}
};
}
}
interface UserService {
void hello();
}