封装
即 数据的隐藏。 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,称为信息隐藏。
高内聚:类内部细节由自己完成。 低耦合:仅仅暴露少量方法供外部使用。
参考https://www.runoob.com/java/java-encapsulation.html
记住:属性私有,get/set
文件位置: 基础语法–>OOP–>Demo04
意义:1.提高程序安全性,保护数据
2.隐藏代码实现细节
3.统一接口,让它们通过接口来访问。
4.系统可维护性增加啦
继承
1.只有单继承,没有多继承。 一个儿子只能有一个爸爸,一个爸爸可以有多个儿子。
2.子类是父类的拓展。
3.继承关系的两个类,一个是父类(基类),一个是子类(派生类),父类继承子类,使用extends表示。
4.子类和父类之间从意义上讲应该具有“is a”的关系
重点:
- object类(所有类直接或间接继承的父类)
- super,this
- 方法重写
super注意点:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或构造方法中
- super和this不能同时调用构造方法!
VS this:
代表的对象不同:
- this:本身调用者的这个对象
- super:代表父类对象的应用
前提:
- this:没有继承也可以使用
- super:只能在继承条件下才能使用
构造方法:
- this(); 本类的构造
- super; 父类的构造
public class A extends B{
public static void test(){
System.out.println("A=>test()");
}
}
public class B {
public static void test(){
System.out.println("B=>test()");
}
}
测试类
public static void main(String[] args) {
A a=new A();
a.test();//A=>test()
B b=new A(); //注意这里,A是子类,父类的引用指向子类/ 爸爸可以向儿子借东西
/**
* 这里有关多态。 这个式子只和左边定义的B b有关
* 和右边的new ___ 无关
* 原因:A,B的方法都是静态方法
*/
b.test(); //B=>test()
}
再看看下一个例子有助于理解这个原理——
public class A extends B{ //这里没有static 可选择重写
@Override //重写,属于有功能的注释。
public void test() { //子类重写方法修饰符不应比父类严格。
System.out.println("A=>test()");
}
}
public class B { //这里没有static
public void test(){
System.out.println("B=>test()");
}
}
//测试类
public static void main(String[] args) {
A a=new A();
a.test();//A
B b=new A(); //注意这里 子类重写了父类的方法
b.test(); //A
}
一个原理:静态方法是类的方法,而非静态方法是对象的方法。
即b是A new 出来的对象,因此调用了A的方法
静态方法和非静态方法区别很大
alt+insert ,overide
**重写:**需要有继承关系,子类重写父类的方法
- 方法名必须相同
- 参数列表必须相同(不相同为重载)
- 修饰符: 范围可以扩大但不能缩小(子类重写方法修饰符不应比父类严格。) public> protected>Default>private
- 抛出的异常范围:可以被缩小,但不能扩大 ClassNotFoundException -->Exception(大)
重写:子类和父类方法名,参数必须一致,方法体可以不同
多态
即同一方法可以根据发送对象的不同而采用多种不同的行为方式,
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多。
public class Student extends Person {
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
public class Person {
public void run(){
}
}
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student()
//但它可以指向的引用类型就不确定了:父类的引用类型指向子类
Student s1=new Student();
//子类能调用的方法,都是自己的或者继承父类的。
//Person 父类型,可以指向子类,但是不能调用子类独有的方法。
Person s2=new Student();
Object s3=new Student();
s2.run();//son
s1.run();//son
//子类重写父类的方法,则执行子类
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大。
// s2.eat(); 报错
((Student) s2).eat(); //不报错
}
多态注意事项:
- 多态是方法的多态, 而属性没有多态
- 父类和子类,有联系 才能多态。 类型转换异常:ClassCastException
- 存在条件: 继承关系,方法需要被重写,父类引用指向子类对象! Father f1=new son();
不需要重写的:
-
static 方法,属于类,它不属于实例
-
final 常量
-
private方法
public static void main(String[] args) {
/**
* Object>String
* Object> Person>Teacher
* Object>Person>Student
*/
Object object=new Student();
//System.out.println(x instanceof y); 编译是否通过?看x和y之间是否有父子关系
instanceof
可以判断两个类之间是否存在父子关系
System.out.println(object instanceof Student); //true
System.out.println(object instanceof Person);//true
System.out.println(object instanceof Object);//true
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
System.out.println("=========================");
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(person instanceof String);//编译报错
System.out.println("=================================");
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);//编译报错
}
子类与父类的转换
public class Application {
public static void main(String[] args) {
//类型之间的转换 :父----子
//子类转换成父类可能会丢掉一些方法
//高---低
Person obj=new Student();
//student将这个对象转换成Student类型,我们就可以使用student类型的方法了
Student student=(Student) obj;
student.go();
//或者
((Student) obj).go();
}
}
/**
* 1.子类转父类:向上转型,直接转,丢失子类中原本可以直接调用的特有方法,
* 2.父类转子类:向下转型,强制转
*/
public class Student extends Person {
public void go(){
System.out.println("go");
}
}