面向对象三大特性
封装
- 该露的露 该藏的藏
- 我们程序设计要追求"高内聚 低耦合" 高内聚就是类的内部数据操作细节自己完成 不允许外部干涉 低耦合 仅暴露少量的方法给外部使用
- 封装(数据的隐藏)
- 通常 应禁止直接访问一个对象中的数据的实际表示 而应通过操作接口来访问 这称为信息隐藏
- 记住这句话 属性私有 get/set
封装的意义
- 提高程序的安全性 保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统的可维护性增加了
//类 private 私有
public class Student {
//属性私有
//名字
private String name;
//学号
private int id;
//性别
private char sex;
private int age;
//提供一些可以操作的这个属性的方法
//提供一些public的get set方法
//get 获得这个数据
public String getName(){
return this.name;
}
//set 给这个数据设置值
public void setName(String name){
this.name=name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>120 || age<0){
this.age=3;
}else {
this.age = age;
}
}
}
Student s1 = new Student();
s1.setName("大刘");
System.out.println(s1.getName());
s1.setAge(999);
System.out.println(s1.getAge()); ==>3 //setAge中进行处理
}
继承
- 继承的本质是对某一批类的抽象 从而实现对现实世界更好的建模
- extends的意思是扩展 子类是父类的扩展
- java中类只有单继承 没有多继承
- 继承是类和类之间的一种关系 除此之外 类和类之间的关系还有依赖 组合 聚合等
- 继承关系的两个类 一个为子类(派生类) 一个为父类(基类) 子类继承父类 使用关键字extends来表示
- 子类和父类之间 从意义上将应该是具有 is a 的关系
- object类
- super
- 方法重写
public class Person {
public void say(){
System.out.println("说话");
}
private int money = 10_0000_0000;
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
//public
//protected
//default
//private
//ctrl+h 打开继承树
}
public static void main(String[] args) {
Student s1 = new Student();
s1.say();
System.out.println(s1.getMoney());
}
super
- super调用父类的构造方法 必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
VS this
- 代表的对象不同
- this 本身调用者这个对象
- super 代表父类对象的应用
- 前提
- this 没有继承也可以使用
- super 只能在继承条件下 才可以使用
- 构造方法
- this() 本类的构造
- super() 父类的构造
public class Person {
protected String name="big6";
public void print(){
System.out.println("Person");
}
//私有的东西无法被继承
}
public class Student extends Person {
private String name="big7";
public void test(String name){
System.out.println(name); //方法的形参name
System.out.println(this.name); //本类的属性name
System.out.println(super.name); //父类的属性name
}
public void print(){
System.out.println("student");
}
public void test1(){
print(); //调用本类的方法print
this.print(); //调用本类的方法print
super.print(); //调用父类的方法print
}
}
重写
-
需要有继承关系 子类重写父类的方法
- 方法名必须相同
- 参数列表必须相同
- 修饰符 范围可以扩大 public>protected>default>private
- 抛出的异常 范围 可以被缩小 但不能扩大
-
子类的方法和父类必须要一致 方法体不同
-
为什么需要重写
- 父类的功能 子类不一定需要 或者不一定满足 Alt+Insert override
//重写都是方法的重写 和属性无关
public class B {
public void test(){
System.out.println("B=>test()");
}
}
//继承
public class A extends B{
//Override重写
@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()
}
}
多态
- 动态编译 可扩展性强
- 即同一方法可以根据发送的对象的不同而采用多种不同的行为方式
- 一个对象的实际类型是确定的 但可以指向对象的引用的类型有很多
- 多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
- 多态是方法的多态 属性没有多态性
public class Person {
public void run(){
System.out.println("person run");
}
public void say(){
System.out.println("person say");
}
}
public class Student extends Person{
@Override
public void run() {
System.out.println("student run");
}
public void doing(){
System.out.println("student doing");
}
}
public class Testing {
public static void main(String[] args) {
Student s1 = new Student();
s1.run();
s1.doing();
s1.say(); //继承父类的方法
//student能调用的是自己或者继承的方法
System.out.println("==============");
Person person = new Person();
person.run();
System.out.println("=============");
Person s2 = new Student();
//父类引用指向子类对象
s2.run();
//子类重写了父类的方法 所以执行子类方法
((Student) s2).doing();
//强制转换成子类 执行子类特有的方法
}
}
student run
student doing
person say
==============
person run
=============
student run
student doing
无法重写
- static 方法 属于类 不属于实例
- final 常量
- private 方法
instanceof
public class Application {
public static void main(String[] args) {
//Object>String
//Object>Person>Teacher
//Object>Person>Student
Object object = new Student();
//System.out.println(x instanceof y); //能否编译通过 就看是否有父子关系
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 Person {
public void run(){
System.out.println("person run");
}
}
public class Student extends Person {
public void go(){
System.out.println("student go");
}
}
public class Application {
public static void main(String[] args) {
//类型之间的转化 :
//高转低
Person p1 = new Student();
//将p1转换成Student类型 就可以使用Student的方法了
Student s1= (Student) p1;
s1.go();
//低转高 子类转父类 可能丢失自己本来的一些方法
Student s2 = new Student();
Person p2=s2;
//p2.go();
}
}