特点:封装、继承、多态
封装:
封装是为了提高访问和修改数据的安全性,方式是控制访问者的信息,我们可以在公开的方法中设置判断,限制访问者的权限[是否可以获取到私有变量] Java的封装就是加private修饰,对类中的属性进行私有 不能直接访问和修改,需要通过类中的方法间接访问
public class Student { private String name; //姓名 private int age; //年龄 public void setName(String name) { System.out.println(new Date()+" ,设置了姓名为:"+name); this.name = name; } public void setAge(int age) { System.out.println(new Date()+" ,设置了年龄为:"+age); this.age = age; } public static void main(String[] args) { Student student = new Student(); student.setName("double"); //Thu Dec 23 22:16:41 CST 2021 ,设置了姓名为:double student.setAge(23); //Thu Dec 23 22:16:41 CST 2021 ,设置了年龄为:23 } }
继承:
继承的作用简单来说就是减少子类中的冗余代码,将子类中共有的代码抽取到父类中。 继承关键字:extends,Java的继承是单继承,只能有一个直接父类,但可以有多个间接父类 Java的类都是继承父类没有extends,就隐式继承Object。
Student和Teacher都含有相同的参数,
public class Student extends Person { private String name; private int 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; } } public class Teacher extends Person { private String name; private int 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; } }
我们可以将上面的两个类中相同的代码抽取到父类中如下:
public class Person { private String name; private int 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; } } public class Student extends Person { } public class Teacher extends Person { } public class Test { public static void main(String[] args) { Student student = new Student(); student.setName("小明"); student.setAge(13); Teacher teacher = new Teacher(); teacher.setName("王老师"); teacher.setAge(33); System.out.println(student.getClass()); //class com.code.Oop01.Student } }
正常的继承使用一
public class Base { static { System.out.println("父类静态块"); } { System.out.println("父类的匿名构造块"); } public Base(){ System.out.println("父类的构造函数"); } } public class Son extends Base { static { System.out.println("子类的静态块"); } { System.out.println("子类的匿名构造块"); } public Son(){ //在子类的第一行默认有个super(); 如果父类提供了一个构造函数是默认无参的,可以不写,也可以写super(); //如果父类没有提供构造函数则是无参的,提供了其他参数的父类构造函数,子类的构造函数必须显示的使用super(具体的参数)来显示调用父类的构造函数 System.out.println("子类的构造函数"); } } public class Test { public static void main(String[] args) { Son son = new Son(); //创建子类对象一定依赖父类 /* 父类静态块 子类的静态块 父类的匿名构造块 父类的构造函数 子类的匿名构造块 子类的构造函数 */ Base base=new Base(); /* 父类静态块 父类的匿名构造块 父类的构造函数 */ } }
正常的继承使用二
super()关键字的使用 若父类无参可不写 父类有参必须写 super()和this()关键字区别 都必须在第一行 所以构造函数中这两不能共存 super()和this()关键字区别 super()肯定继承的父类变量、方法、构造函数 this()可能是自己的变量、方法public class Base { public Base(int a){ System.out.println("父类的构造函数:"+a); } } public class Son extends Base { public Son(int a){ //在子类的第一行默认有个super(); super(a); System.out.println("子类的构造函数:"+a); } public static void main(String[] args) { Son son = new Son(10); /* 父类的构造函数:10 子类的构造函数:10 */ } }多态:同一个方法名 不同的实现结果 多态就是同一个方法名,不同的实现内容和结果,具体体现就是方法重载和方法重写 方法重载 一个类中 在一个类中,方法名相同,不同的参数列表,与返回值类型无关 决定调用哪个重载的方法是在编译期间(java class),参数的个数就决定了 所以调用哪个重载的方法是由参数决定的,方法重载也叫编译时多态 static修饰的方法重载,也是方法重载。 方法重写,也叫方法覆盖,在继承关系中,也叫运行时多态class,运行class字节码文件 子类和父类具体相同的方法名,相同的参数列表(相同的参数个数和类型) 相同的返回值类型,我们称为方法重写,也叫方法覆盖 如果static关键字修饰的方法重写,不是方法重写,调用哪个是根据来决定的。
子类中没有speak()方法则使用父类的speak()方法,子类有speak()方法则使用子类中的speak()方法
public class Person { public void speak(){ System.out.println("人们在我耳边轻语..."); } } public class Teacher extends Person{ public void speak(){ System.out.println("老师在我耳边轻语..."); } public static void main(String[] args) { Teacher teacher = new Teacher(); teacher.speak();//老师在我耳边轻语... } }
public class Person { public void speak(){ System.out.println("人们在我耳边轻语..."); } } public class Teacher extends Person{ public static void main(String[] args) { Teacher teacher = new Teacher(); teacher.speak();//人们在我耳边轻语... } }
重载:在一个类中,方法名相同,参数不同,对权限没有要求。【编译时多态】
public class Student { public void study(){ System.out.println("看书"); } public void study(double money){ System.out.println("书的价格:"+money); } public void study(String name){ System.out.println("学生姓名:"+name); } public static void main(String[] args) { Student student = new Student(); student.study(); //看书 student.study("隔壁老王"); //学生姓名:隔壁老王 student.study(20.99); //书的价格:20.99 } }
声明的父类对象,new的是子类的对象 一个父类可以指向继承他的子类,叫做动态绑定。
public class Person { public void speak(){ System.out.println("人们在耳边轻语..."); } } public class Teacher extends Person{ public void speak(){ System.out.println("老师在耳边轻语..."); } public static void main(String[] args) { //声明的父类对象,new的是子类的对象 一个父类可以指向继承他的子类,叫做动态绑定。 Person teacher = new Teacher(); teacher.speak();//人们在我耳边轻语... } }
静态方法也叫类方法,是属于这个类,而不仅仅属于某个对象 静态方法的继承 若子类与父类有相同的静态方法 前缀名是谁的就用谁的
public class Base { public static void show(){ System.out.println("父类的show"); } } public class Son extends Base{ public static void show(){ System.out.println("子类的show"); } public static void main(String[] args) { //静态方法的继承 若子类与父类有相同的静态方法 前缀名是谁的就用谁的 Base base=new Base(); base.show(); //父类的show Son son=new Son(); son.show(); //子类的show Base base1=new Son(); base1.show(); //父类的show } }