面向对象2

1. 三大特性的理解


在编写代码时,我们追求”高内聚 低耦合” ,达到重用与规范, 则需要使用面向对象的三大特性来实现:


  • 封装:encapsulation 隐藏信息

  • 继承:inheritance 延续+扩展父类信息

  • 多态:polymorphism 模糊策略 以不变应万变

2. 面向对象:封装性


2.1. 什么是封装

程序设计要追求“ 高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部 干涉;低耦合:仅暴露少量的方法给外部使用。也就是说,用户无需知道对象内部方法的实现细节,但可以根据 对象提供的外部接口(对象名和参数)访问该对象。

2.2 作用

1. 提高代码的重用性,将同一个类的相同属性或功能封装在一起,而其他的具有相同属性和方法的类不用再次编写该功能,而是直接拿来使用

//将相同的属性和功能封装在一起
public class TheSame{
    //人具有名字,年龄,性别等相同的属性
    //姓名
    public String name;
    //年龄
    public int age;
    //性别
    public boolean gender;
    
    //具有睡觉,吃饭,工作同一功能
    void sleep(){
        System.out.println(this.name+"正在睡觉");
    }
    
    void eat{
        System.out.println(this.name+"在吃火锅");
    }
    
    void gender(){
        System.out.println(this.name+"的性别为:"+this.gender);
    }
}
//学生类继承或调用
public class Student extends Person{
    //学生具有的属性
    //学生编号
    public int id;
    //功能
    void study(){
        //在这里使用到了父类的属性
        System.out.println("年仅"+this.age+"的"+this.name+"正在学习");
    }
}
//测试类(具有main方法的类)
public class Test{
    Student student=new Student();
    student.name="小明";
    student.age=18;
    //调用sleep方法
    student.sleep();
    //调用dining方法
    student.dining();
    //调用study方法
    student.study();
}
 

  1. 隐藏信息,实现细节。通过控制访问权限可以将可以将不想让客户端程序员看到的信息隐藏起来, 如某客户的银行的密码需要保密,只能对该客户开发权限。

3. 修饰符

3.1权限修饰符
  • public(公共权限):

    可以修饰类,成员变量;成员方法,构造方法

    被public修饰的成员可以在任何一个类中被调用,不管是不是同包下的类,是权限最大的一个修饰符

  • protected(受保护权限):

    • 可以修饰成员变量,成员方法,构造方法,不能修饰类(外部类和内部类不考虑)

    • 被private修饰的成员只能在定义他们的类中使用,在其他类中不能调用

    • 如果有不同包的类想调用它们,那么这个类必须是定义它们的子类

  • default(默认权限)

    • 类,成员变量,成员方法,构造方法都能使用默认权限,即不写任何关键字

    • 默认权限即同包权限,同包权限的元素只能在定义它们的类中使用,以及同包的类中被调用

  • private:(私有权限)

    • 可以修饰成员变量,构造方法,成员方法,不能修饰类(外部类,内部类不考虑)

    • 被private修饰的成员,只能在定义它们的类中使用,在其他类中不能调用


注意:

  • 并不是每个修饰符都可以修饰类,只有public和default可以

  • 所有修饰符都可以修饰数据成员,方法成员,构造方法

  • 为了代码安全起见,修饰符不要尽量使用权限大的,而是适用即可。比如,成员变量,如果没有特殊需要,尽可能用private.

  • 修饰符修饰的是”被访问”的权限


修饰符同类中同一个包中(子类和无关类)不同包(子类)不同包(无关类)
public Y Y Y Y
protected Y Y Y N
默认 Y Y N N
private Y N N N
3.2 抽象修饰符
  • abstract

    • 抽象的意思,不能修饰构造方法,不能修饰成员变量,可以修饰类,成员方法

    • 被修饰的类不能被实例化,只能被继承,被修饰的成员方法在子类中必须被重写


  • 抽象类 :abstract修饰的类就是抽象类

  • 抽象方法: abstract修饰的方法就是抽象方法

注意:abstract关键字不能与private,final,static,和native一起使用

3.3 状态修饰符
  • static

    • 静态的意思,可以修饰成员变量,成员方法,不能修饰类,不能修饰构造方法

    • 被修饰的变量,方法可以通过类名进行调用

  • final

    • 最终的意思,可以修饰类,成员变量,成员方法,不能修饰构造方法

    • 修饰的类不能被继承,被修饰的变量是常量,被修饰的方法不能被继承

4. 类型转换

4.1 基本数据类型
  • 自动类型转换 :

    数字表示范围小的数据类型可以自动转换成范围大的数据类型。byte<short<int<float<long<long<double。如:

    int i=100;
    long j1=200;
    long j2=i;//int类型自动转为long类型
    float f=j1;//long类型自动转为float类型
  • 强制类型转换:

    即强制显示的把一个数据类型转换为另外一种数据类型,在基本数据类型中也就是大转小,例如:

    short s=122;
    int i=s;//小转大,自动类型自动转 i=122
    double d=12.33;
    long c=(long)d;//long类型比double类型小,c=10
4.2. 应用类型
  • 自动类型转换

    当子类继承类父类后

    父类范围大于子类:父类 Father 子类 Son

    Father father=new Son();//自动转换,向上转型
  • 强制类型转换
    
    
    //父类 Father
    //子类 Son
    //Son exdents Father
    Father father=new Son();
    Son son=(Son)father;
  • instanceof

    判断前面 的引用是否指向为后面类型的对象,如果是返回true,如果不是返回false;

     

    public class Cast {
        public static void main(String[] args) {
            //多态    向上转型
            Person p =new Student(); 
            System.out.println(p.name);
            p.sleep();
            //向下转型
            //Student s =(Student)p;
            //判断
            if(p instanceof Teacher) {
                Teacher s= (Teacher)p;
                //子类独有内容
                System.out.println(s.id);
                s.haha();
            }else if(p instanceof Student) {
                Student s =(Student)p;
                System.out.println(s.id);
                s.haha();
            }
        }
    }

     

     

     

    当先要多态引用调用子类独有内容时候,需要向下转型,配合instaceof一起使用,先判断后转型,预防两个类型转换异常出现

5.多态

多态是同一个行为具有多个不同表现形式或形态的能力;多态就是同一个接口,使用不同的实例而执行不同操作。


  • 多态优点
    1. 消除类型之间的耦合关系

    2. 可替换性

    3. 可扩充性

    4. 接口性

    5. 灵活性

    6. 简化性

  • 多态存在的三个必要条件
    • 必须发生继承

    • 重写:子类重写父类方法

    • 父类引用指向子类对象

    比如:

    class Parent{
        void test(){
           System.out.println("自我良好"); 
        }
    }
    class Child extends Parent{
        void test(){
            System.out.println("睡眠不足");
        }
    }
    public class Test{
        public static void main(String[] args) {
            Parent p = new Child();
            p.test();//结果为 "睡眠不足"
        }
    }

     

     

    当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

    public class Test {
        public static void main(String[] args) {
          show(new Cat());  // 以 Cat 对象调用 show 方法
          show(new Dog());  // 以 Dog 对象调用 show 方法
                    
          Animal a = new Cat();  // 向上转型  
          a.eat();               // 调用的是 Cat 的 eat
          Cat c = (Cat)a;        // 向下转型  
          c.work();        // 调用的是 Cat 的 work
      }  
                
        public static void show(Animal a)  {
          a.eat();  
            // 类型判断
            if (a instanceof Cat)  {  // 猫做的事情 
                Cat c = (Cat)a;  
                c.work();  
            } else if (a instanceof Dog) { // 狗做的事情 
                Dog c = (Dog)a;  
                c.work();  
            }  
        }  
    }
     
    abstract class Animal {  
        abstract void eat();  
    }  
      
    class Cat extends Animal {  
        public void eat() {  
            System.out.println("吃鱼");  
        }  
        public void work() {  
            System.out.println("抓老鼠");  
        }  
    }  
      
    class Dog extends Animal {  
        public void eat() {  
            System.out.println("吃骨头");  
        }  
        public void work() {  
            System.out.println("看家");  
        }  
    }
    ​
    ​
    //运行结果为:
    吃鱼
    抓老鼠
    吃骨头
    看家
    吃鱼
    抓老鼠
    
    
posted @ 2020-03-27 22:08  smile马伊子  阅读(151)  评论(0)    收藏  举报