面向对象编程的三大特性

面向对象编程的三大特性

封装

  1. 该露的露,该藏的藏

    我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。

  2. 封装(数据的隐藏)

    通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。

  3. 记住这句话就够了:属性私有,get/set

    //类 private: 私有
    public class Student {
    //属性私有
    private String name;
    private  int age;
    private char sex;
    
    //提供一些可以操作这些属性的方法
    //提供一些public的get,set方法
    
    //get 获得这个数据
    public String getName(){
        return this.name;
    }
    
    //set 给这个数据设置值
    public void setName(String name){
        this.name = name;
    }
    
    //快捷键 Alt+Insert 自动生成get、set方法
    
    
    
     public int getAge() {
         return age;
     }
     
     public void setAge(int age) {
         if(age>0 && age <=120){
             this.age = age;
         }else{
            this.age = 3;//不合法的
         }
     
     }
     public char getSex() {
         return sex;
     }
     
     public void setSex(char sex) {
         this.sex = sex;
     }
    
    
    
    
    
    
    

public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();

        s1.setName("jjlin");
    
        System.out.println(s1.getName());//jjlin
    
        s1.setAge(9);
    
        System.out.println(s1.getAge());
    
    }

}

  1. 封装的好处
    • 提高程序的安全性,保护数据.
    • 隐藏代码的实现细节
    • 统一接口
    • 系统的可维护性增加了

继承

  1. 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。

  2. extands的意思是“扩展”。子类是父类的扩展。

  3. JAVA中类只有单继承,没有多继承! 一个儿子只能有一个爸爸,但一个爸爸可以有多个儿子

  4. 被final修饰的类不能被继承。

  5. 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。

    • 继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
    • 子类和父类之间,从意义上讲应该具有"is a"的关系.
    • 快捷键 Ctrl + H ,可以显示类之间的关系
    //先定义一个父类
    //在Java中,所有的类,都默认直接或或者间接继承object
    //Person一个类 :父类
    public class Person /*extends object*/ {
        /*
        四个修饰符
            1.public  方法用继承都用public
            2.protected
            3.default
            4.private  属性一般用private
         */
       private  int money = 10_0000_0000;
       public void say(){
           System.out.println("说了一句话");
       }
    }
    
    public int getMoney() {
        return money;
    }
    
    public void setMoney(int money) {
        this.money = money;
    }
    
    
//后定义子类
//Student is 人 :派生类,子类
//子类继承了父类,就会拥有父类的全部方法
public class Student extends Person {

}

//Teacher is 人 :派生类,子类
public class Teacher extends Person {
}

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();//说了一句话
        student.setMoney(10_0000); 
        System.out.println(student.getMoney());//100000

    }
}

  1. object类

​ java中的所有类都直接或间接继承Object类

  1. super

    //定义一个父类
    public class Person /*extends object*/ {
         protected String name = "kuangshen" ;
    
         public void print(){
             System.out.println("Person");
         }
    }
    
    //定义一个子类
    public class Student extends Person {
    
        //快捷键 Ctrl + H   显示父类
    
        private String name = "qinjiang";
    
        public void print(){
            System.out.println("Student");
        }
    
        public void test1(){
            print(); //Student
            this.print(); //Student
            super.print(); //Person
    
        }
    
        public void test(String name){
            System.out.println(name);//jjlin
            System.out.println(this.name);//qinjiang
            System.out.println(super.name);//kuangshen
        }
    
    //应用
    public class Application {
        public static void main(String[] args) {
            Student student = new Student();
            student.test("jjlin");
            student.test1();
    
        }
    }
    

    注意:请仔细分辨各个输出,理清super和this之间的关系。

    • 构造器的不同

      //父类
      public class Person {
          //一个类即使什么都不写,它也会存在个方法
          //显示的定义构造器
          public Person(){
              System.out.println("Person");
          }
          //有参构造:一旦定义 了有参构造。无参就必须显示定义
          public Person(String name){
              this.name = name ;
          }
        
      }
      
      //子类
      public class Student extends Person{
          public Student() {
             //super();是隐藏代码,默认是先调用父类的无参构造器再调用子类的构造器
              super(); // 隐藏代码:调用了父类的无参构造,调用父类的构造器,必领要在子类构造器的第一行
              System.out.println("Student无参执行了");
          }
          public Student(String name) {
              this .name = name ;
          }
      }
      
  • super注意点:

​ super调用 父类的构造方法,必须在构造方法的第一个

​ super 必须只能出现在子类的方法或者构造方法中!

​ super和 this 不能同时调用构造方法!

​ Vs this:

​ 代表的对象不同:
​ this 本身调用者这个对象
​ super:代表父类对象的引用

​ 前提
​ this:没有继承也可以使用
​ super:只能在继承条件才可以使用

​ 构造方法
​ this() ; 本类的构造
​ super():父类的构造!

  1. 重写

    父类静态方法

    //子类
    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 class Application {
        public static void main(String[] args) {
            //方法的调用只和左边,定义的数据类型有关
            
            A a = new A();
            a.test();//A==>test()
            
            //父类引用指向了子类
            B b = new A();
            b.test();//B==>test()
        }
    }
    

​ 父类非静态方法

//父类
//重写都是方法的重写,和属性无关
public class B  {
    public void test(){
        System.out.println("B==>test()");
    }
}
//子类
public class A extends B{

    //Override就是方法的重写
    //快捷键Alt+Insert,选中Override可以自动生成,不用写
    @Override //注解:有功能的注释
    public void test() {
        super.test();
    }
}
public class Application {
    public static void main(String[] args) {
        /*
            静态方法和非静态方法区别很大
            静态方法:方法的调用只和左边,定义的数据类型有关
            非静态方法:重写,父类方法只能是public
         */

        A a = new A();
        a.test();//B==>test()

        //父类引用指向了子类
        B b = new A();
        b.test();//B==>test()
    }


}

重写:需要有继承关系,子类重写父类的方法!

  • 方法名必须相同
  • 参数列表列表必须相同
  • 修饰符:范围可以扩大但不能缩小:public>Protected >Default>private
  • 抛出的异常:范围,可以被缩小,但不能扩大: ClassNotFoundException --> Exception(大)
  • 重写,子类的方法和父类必要一 致;方法体不同!

为什么需要重写:

  • 父类的功能,子类不一定需要, 或者不一定满足!

    比如,把子类的方法重写一次,变为

    //子类
    public class A extends B{
    
        public void test(){
            System.out.println("A==>test()");
        }
    
    }
    
    
    //父类
    //重写都是方法的重写,和属性无关
    public class B  {
        public void test(){
            System.out.println("B==>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()
        }
    
    
    }
    

    注意与上述例子输出的不同,一个是直接继承了父类的方法,输出B==>test(),而子类方法重写之后,输出的是A==>test()

  • Alt +Insert ;---->override;

    多态

  1. 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。

  2. 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多

  3. 多态存在的条件

    • 有继承关系

    • 子类重写父类方法

    • 父类引用指向子类对象

    • 注意:多态是方法的多态,属性没有多态性。

      //父类
      public class Person {
          public void run(){
              System.out.println("run");
          }
      }
      
      //子类
      public class Student extends Person {
          @Override
          public void run() {
              System.out.println("son");;
          }
      
          public void eat(){
              System.out.println("eat");
          }
      }
      
      public class Application {
          public static void main(String[] args) {
             //一个对象的实际类型是确定的
              //new Student();
              //new Person();
      
              //可以指向的引用类型就不确定了,比如父类的引用可以指向子类
      
              //Student 子类型,能调用的方法都是自己的或者继承父类的
              Student s1 = new Student();
      
              //Person 父类型,虽然可以指向子类,但是不能调用子类独有的方法
              Person s2 = new Student();
              Object s3 = new Student();
      
              //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
              s1.run();//son, 子类重写了父类的方法,执行的是子类的方法
              s2.run();//son
              s1.eat();
      
          }
      
      
      }
      
      
  4. 多态注意事项:

    • 多态是方法的多态,属性没有多态
    • 父类和子类,有联系 。如果类型转换异常!,就会报错ClassCastException!
    • 存在条件: 有继承关系,方法需要重写,父类引用指向子类对象! Father f1 = new Son();如果子类重写了父类的方法,父类引用如果指向了子类对象,执行的就是子类重写的方法。
    • 不能进行多态的方法:
      • static 方法,属于类,它不属于实例
      • final常量;
      • private 方法;
  5. instanceof:(类型转换)引用类型, 判断一个对象是什么类型~,可以判断两个类之间是否存在父子关系

    //父类
    public class Person {
        public void run(){
            System.out.println("run");
        }
    }
    
    //子类1
    public class Student extends Person {
        public void go(){
            System.out.println("go");
        }
    }
    
    //子类2
    public class Teacher extends Person {
    
    }
    
    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(person instanceof String); //编译就已经报错
    
    
        }
    
    
    }
    
    
  6. 转换

    • 父类转子类

      public class Application {
          public static void main(String[] args) {
                 //类型之间的转化: 父 -----> 子 需要向下强制转换
      
                //父                子
                Person obj = new Student();
      
                //Student 将这个obj对象强制转换为Student类型,就可以使用Student类型的方法了
              ((Student) obj).go();
      
      
          }
      
      
      }
      
    • 子类转父类

      public class Application {
          public static void main(String[] args) {
      
              //子类转换为父类,可以直接转换,但可能会丢失自己本来的一些方法
              Student student = new Student();
              student.go();
              Person person = student;
              //person.go();  //  person丢失了go方法
      
          }
      
      
      }
      
      /*
      子转父:向上转型,直接转,但会丢失子类中原本可以直接调用的特有方法
      父转子:向下转型,需要强制转换
       */
      

    总结

    • 父类引用指向子类的对象
    • 把子类转换为父类,向上转型;
    • 把父类转换为子类,向下转型;强制转换
    • 方便方法的调用,减少重复的代码!j简洁
    • 封装、继承、多态! 抽象类,接口

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值