袁艺

个人站

欢迎来到我的个人站~


面向对象三大特征

封装

封装:顾名思义,隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。 封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过 外部接口,一特定的访问权限来使用类的成员。 封装的大致原则: 1、把尽可能多的东西藏起来.对外提供简捷的接口.
2、把所有的属性藏起来.
3、封装好处:将变化隔离;便于使用;提高重用性;安全性。
封装的意义:
  封装的意义在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。

  1. 保护数据成员,不让类以外的程序直接访问或修改,只能通过提供的公共的接口访问==>数据封装。

  2. 方法的细节对用户是隐藏的,只要接口不变,内容的修改不会影响到外部的调用者==>方法封装。

  3. 当对象含有完整的属性和与之对应的方法时称为封装。

  4. 从对象外面不能直接访问对象的属性,只能通过和该属性对应的方法访问。

  5. 对象的方法可以接收对象外面的消息。

    类成员的访问修饰符:
       即类的方法和成员变量的访问控制符,一个类作为整体对象不可见,并不代表他的所有域和方法也对程序其他部分不可见,需要有他们的访问修饰符判断。

    权限如下:
  public protected 默认 private
本类中 yes yes yes yes
同包中(有继承关系) yes yes yes no
同包(没有继承关系) yes yes yes no
不同包(有继承关系) yes yes no no
不同包(没有继承关系) yes no no no

总结:
public 修饰的可以在同包或者不同包中被访问
protected 同包或者不同包的子类可以被访问
默认 只能在自己的包中被访问,跨包则无法访问
private 只能在本类中被访问

继承

​ 继承大概分为两种,一种是“有”的关系(has a);另一种是“是”的关系(is a)

一、has a

在一个类中包含着另一个类
举例:
图书管理系统中学生类里面要包含教师类来说明该学生的老师是谁:

public class Student {
private String sID;
private String name;
private String sex;
private int age;
private String clazz;

private Teacher teacher;

二、is a

  1.使用extends关键字来继承父类,只能继承父类中非私有的属性和方法。
  2.一个子类只能继承一个父类,但父类可以由多个子类
  3.子类的继承可以传递

4.父类的构造方法在子类中的使用:

默认子类的构造方法的第一句都会调用父类无参数的构造方法  super();

如果父类没有无参数的构造方法,使用super(实际参数)

只要手动的调用super关键字,默认的super就不会存在

super()必须放在第一句

继承特点:
1.单继承
2.一个子类只能继承一个父类,一个父类可以有多个子类
3.可以传递继承
4.子类继承了父类的非私有的属性和方法

关于继承的几点注意:
a) 父类有的,子类也有
b) 父类没有的,子类可以增加
c) 父类有的,子类可以改变
d) 构造方法不能被继承
e) 方法和属性可以被继承
f) 子类的构造方法隐式地调用父类的不带参数的构造方法
g) 当父类没有不带参数的构造方法时,子类需要使用super来显式地调用父类的构造方法,super指的是对父类的引用
h) super关键字必须是构造方法中的第一行语句。

多态

多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

Java实现多态有三个必要条件:继承、重写、向上转型。

  • 继承:在多态中必须存在有继承关系的子类和父类。

  • 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

  • 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。 ​ 体现1:
          父类person
          子类:Doctor extends Person
            Person p=new Doctor()  

理解:

  1. 子类创建的对象给父类赋值

  2. 如果子类的地址赋值给父类,父类拥有自己的功能部分,不能调用子类特有的属性和方法

  3. 父类调用方法的话,只能调用父子共同拥有的方法和属性,但是如果有方法发生重写了,则调用重写之后的方法

体现2:向下转型

instranceof 判断参数类型。格式:对象 instranceof 类名 

  • person instranceof Doctor 向下转型必须判断传递的对象是什么类型的,否则容易出错。父类的范围比较大,包含的子类比较多比如Person类中有Doctor、policeman、teacher几个类,用父类person接参后发生自动的向上转型,如果不判断参数的类型而直接向下转型jvm不知道之前的实参是什么类型,所以会报错

  • 比如你是一个酒神,对酒情有独钟。某日回家发现桌上有几个杯子里面都装了白酒,从外面看我们是不可能知道这是些什么酒,只有喝了之后才能够猜出来是何种酒。你一喝,这是剑南春、再喝这是五粮液、再喝这是酒鬼酒….在这里我们可以描述成如下:

  •  a = 剑南春
     b = 五粮液</font><br>
     c = 酒鬼酒</font><br>
     …    
    
    
  •  这里所表现的的就是多态。剑南春、五粮液、酒鬼酒都是酒的子类,我们只是通过酒这一个父类就能够引用不同的子类,这就是多态——我们只有在运行的时候才会知道引用变量所指向的具体实例对象。诚然,要理解多态我们就必须要明白什么是“向上转型”。在继承中我们简单介绍了向上转型,这里就在啰嗦下:在上面的喝酒例子中,酒(Win)是父类,剑南春(JNC)、五粮液(WLY)、酒鬼酒(JGJ)是子类。我们定义如下代码:JNC a = new  JNC(); 对于这个代码我们非常容易理解无非就是实例化了一个剑南春的对象嘛!但是这样呢?Wine a = new JNC();在这里我们这样理解,这里定义了一个Wine 类型的a,它指向JNC对象实例。由于JNC是继承与Wine,所以JNC可以自动向上转型为Wine,所以a是可以指向JNC实例对象的。这样做存在一个非常大的好处,在继承中我们知道子类是父类的扩展,它可以提供比父类更加强大的功能,如果我们定义了一个指向子类的父类引用类型,那么它除了能够引用父类的共性外,还可以使用子类强大的功能。 但是向上转型存在一些缺憾,那就是它必定会导致一些方法和属性的丢失,而导致我们不能够获取它们。所以父类类型的引用可以调用父类中定义的所有属性和方法,对于只存在与子类中的方法和属性它就望尘莫及了
public class Wine {

   public void fun1(){

       System.out.println("Wine 的Fun.....");

     fun2();
  }

    public void fun2(){
        System.out.println("Wine 的Fun2...");
    }
}

public class JNC extends Wine{
  /**
* @desc 子类重载父类方法
* 父类中不存在该方法,向上转型后,父类是不能引用该方法的

* @param a

* @return void
          */
          public void fun1(String a){
            System.out.println("JNC 的 Fun1...");
              fun2();
          }

   /**
* 子类重写父类方法
* 指向子类的父类引用调用fun2时,必定是调用该方法
           */
          public void fun2(){
              System.out.println("JNC 的Fun2...");
         }
      }

public class Test {
    public static void main(String[] args) {
       Wine a = new JNC();
        a.fun1();
   }
}
-------------------------------------------------
Output:

Wine 的Fun.....

JNC 的Fun2...

分析:在这个程序中子类JNC重载了父类Wine的方法fun1(),重写fun2(),而且重载后的fun1(String a)与 fun1()不是同一个方法,由于父类中没有该方法,向上转型后会丢失该方法,所以执行JNC的Wine类型引用是不能引用fun1(String a)方法。而子类JNC重写了fun2() ,那么指向JNC的Wine引用会调用JNC中fun2()方法。

在Java中有两种形式可以实现多态。继承和接口

方法的重载

重载:让类以统一的方式处理不同的数据类型的一种手段。是一个类中多态性的一种表现。也叫overload

   特点:

  1. 方法名一样,参数列表不同

  2. 不能通过访问权限、返回类型、抛出的异常进行重载

  3. 方法的异常类型和数目不会对重载造成影响

 场景:一个方法有不同的参数类型

注意:

  1. 重载方法得参数必须不同:
    1. 参数个数不同,如method(int x)与method(intx,int y)不同
    2. 参数类型不同,如method(int x)与method(doublex)不同
    3. 参数顺序不同,如method(int x,double y)与method(doublex,int y)不同
  2. 重载至于方法名和参数类型相关,与返回值无关
    1. 如void method(int x)与int method(int y)不是方法重载,不能同时存在
  3. 重载与具体得变量标识符无关
    1. 如method(int x)与method(int y)不是方法重载,不能同时存在

方法的重写

重写:父类方法在子类中的实现。也叫覆盖override

   特点: 1.发生在子类中
2.方法的定义与父类完全一致
3.改变方法体
4.大于等于父类访问修饰符  public —》子类:public

修饰符访问权限:

大 :public ——》protected ——》 默认的 ——》  private  小

5.静态方法不能被重写为非静态方法
场景;子类继承的父类的方法不能满足当前需求。

参数传递

1

通过上面的两段程序可以得出如下结论:

  • 当调用方法时,如果传入的数值为基本数据类型(包含String类型),形式参数的改变对实际参数不影响

  • 当调用方法时,如果传入的数值为引用数据类型(String类型除外),形式参数的改变对实际参数有影响