JavaSE第七天(面向对象:权限和继承)

    技术2022-07-10  102

    面向对象:权限和继承

    文章目录

    面向对象:权限和继承第一节 三大特性的理解1. 封装:隐藏信息**2.继承:子承父业**3. 多态:模糊策略 第二节 封装1、访问权限 第三节 类的继承1、继承2. 重写3. Object4、实例5.super6、final

    第一节 三大特性的理解


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

    ​ 封装:encapsulation 隐藏信息

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

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

    1. 封装:隐藏信息

    理解:

    ​ 如电脑 利用一个外壳包裹,保护了里面的电器元件,提供了少量的按键与其对接使用。我要看电视,只需要按一下 开关和换台就可以了。有必要了解电视机内部的结构吗?有必要碰碰显像管吗?制造厂家为了方便我们使用电视, 把复杂的内部细节全部封装起来,只给我们暴露简单的接口,比如:电源开关。具体怎么内部实现的,我们不需要 操心。需要让用户知道的暴露出来,不需要让用户了解的全部隐藏起来。这就是封装。白话: “该露的露,该藏的藏“。

    作用:

    ​ a)、实现了专业的分工。将能实现某一特定功能的代码封装成一个独立的实体后,各程序员可以在需要的时候调 用,从而实现了专业的分工,即工作中的分模块、分功能开发。

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

    2.继承:子承父业

    理解:

    ​ 我叫王思聪,我爸是王建林。就是个性对共性的属性与方法的接受,并加入个性特有的属性与方法。 子类与父类的 关系并不只是日常生活中的父子关系,子类与父类而是一种特殊化与一般化的关系,是 is-a 的关系,子类是父类更 加详细的分类。如 class Dog extends Animal,就可以理解为 dog is a animal.注意设计继承的时候,若要让某个类 能继承,父类需适当开放访问权限,遵循里氏代换原则,即向修改关闭对扩展开放,也就是开-闭原则。

    作用:

    ​ 实现代码的复用,延续+扩展父类信息。 继承后子类自动拥有了父类的属性和方法,但特别注意的是,父类的私有 属性和构造方法并不能被继承。另外子类可以写自己特有的属性和方法,目的是实现功能的扩展,子类也可以复写 父类的方法即方法的重写

    3. 多态:模糊策略

    理解:

    ​ 多种形态,今天有好事发生。这个好事很模糊,什么好事呢?学习了很高大上的三大特性。哈哈。 多态的概念发展 出来,是以封装和继承为基础的。子类以父类的身份出现,但做事情时还是以自己的方法实现。子类以父类的身份 出现需要向上转型(upcast),其中向上转型是由 JVM 自动实现的,是安全的,但向下转型(downcast)是不安全的, 需要强制转换。子类以父类的身份出现时自己特有的属性和方法将不能使用。

    作用:

    以不变应万变,如 USB 接口。电脑上的 USB 接口,就是一个标准,凡是实现了这个接口的电子产品如 u 盘、打 印机、手机 都可以与电脑对接。

    注意:java 三大特性虽说简单,但真正能理解其中的含义,没有个一年半载的学习,是理解不了的。 很多同学刚刚 开始接触 java,经常听见三大特性,多态、封装及继承。这时候只是模糊的概念,后来工作了,才慢慢能发觉其中 的奥妙,这就是 java 语言的魅力!

    第二节 封装

    1、访问权限

    ​ 通过访问权限 public protected default private 来封装类、方法及属性,达到隐藏细节的目的,最终达到“该露的 露,不该露的别瞎露”目的。

    同一个类同一个包子类所有类private*default**protected***public****

    2、PO:Javabean


    ​ 在编写 javabean 中通常我们会将这个类的属性全部私有化,外界不能直接通过对象.属性来修改和获取这些属性,我们一般会提供这些属性的get/set方法来获取/设置这些属性的值,做这一步的目的是,可以将外界输入的数据来进一步的判断校验,做一些自己的事情,防止外界乱使用修改我们编写类的属性。

    public class Person { /*私有化属性*/ private String name;//姓名 private int age; //年龄 private boolean sex;//性别 public Person() { } //提供setter与getter方法给外界调用 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { //这里可以做一些简单的校验判断年龄是否合法, //如果没有直接使用对象.属性设置我们程序的可控性就变得很差 this.age = age; } public boolean isSex() { return sex; } public void setSex(boolean sex) { this.sex = sex; } }

    第三节 类的继承

    1、继承

    继承的本质在于抽象。类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。同时使用 继承可以提高代码的复用性。(事实上,利用组合可以更好的实现代码复用!)extends的意思是“扩展”。子类是 父类的扩展。

    语法规则: java中使用extends关键字实现类的继承机制

    修饰符 class 子类名 extends 父类名 {}

    作用:

    1、实现代码的复用,延续+扩展父类信息。

    2、通过继承,子类自动拥有了基类的所有成员(非private的成员变量和成员方法)。

    注意:

    1、java 中只有单继承,没有像 c++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。 “一个 孩子只有一个亲爸爸” 。但是可以多层/多级继承

    2、即 Java只支持单继承,不允许多继承:一个子类只能拥有一个直接基类,但是一个基类可以派生出多个子类

    2. 重写

    父类不满足子类的要求,按需改写。注意 方法签名必须相同

    方法签名:方法名(参数类型,参数类型);方法签名不包括参数类型的变量名

    “==”:方法名、形参列表相同。

    “≤≤”:返回值类型(基本类型必须相同)和异常类型,子类小于等于父类。

    “≥”:访问权限,子类大于等于父类

    class F{ int test(int a){ return a*100; } } class C{ //重写 public int test(int a){//变量名可以不同 return a*100*100; } }

    注意属性不会重写 注意以下方法不会重写

    ​ 静态方法不会重写 ,父类为静态,子类只能为静态,否则编译错误

    ​ final 修饰方法 否则编译错误

    ​ 私有方法不会重写

    3. Object

    Object 类是所有 Java 类的根基类

    如果在类的声明中未使用 extends 关键字指明其基类,则默认基类为 Object

    public class Person { ... } 等价于 public class Person extends Object { ... }
    4、实例

    实例化一个类是从最顶级的超类开始实例化的, 是一层一层的包裹结构. “先父类后子类, 先静态后成员"

    public class F{ static{ System.out.println("父类静态块"); } { System.out.println("=========="); System.out.println("父类构造块"); } public F(){ System.out.println("父类构造器"); } } public class C extends F{ static{ System.out.println("子类静态块"); } { System.out.println("子类构造块"); } public C(){ //super();默认会先执行 System.out.println("子类构造器"); System.out.println("=========="); } } public class Test{ public static void main(String[] args){ //实例化C类的对象 C c = new C(); } }

    结果:

    父类静态块 //先执行父类的静态代码块 子类静态块 //在执行子类的静态代码块 ========== 父类构造块 //先执行父类的构造代码块 父类构造器 //后执行父类的构造器 子类构造块 //先执行子类的构造代码块 子类构造器 //后执行子类的构造器 ==========

    会发现加载顺序为,静态代码块>构造代码块>构造器。先执行父类的在执行子类的。

    因为静态的东西不管时变量还是方法还是代码块,都是属于类的,不属于对象,也就是说当类被加载时就已经执行了,当类的信息被加载完毕时才开始创建对象,此时构造快优先执行,构造器后执行

    5.super

    public class Test { public static void main(String[] args) { new Child().f(); } } class Father { public int value; public Father(){ } public Father(int a){ value =a; System.out.println("Father(int)"); } public void f(){ value = 100; System.out.println("Father.value="+value); } } class Child extends Father { public int value; public Child(){ super(12); } public void f() { super.f(); value = 200; System.out.println("Child.value="+value); System.out.println(value); System.out.println(super.value); } }

    结果

    Father(int) Father.value=100 Child.value=200 200 100

    主方法中创建的时Child类的对象,但是发现有父类,就会先去加载父类,此时如果有静态的就先加载静态的,再加载子类,还是一样如果有静态的就先加载静态的,如果没有或者静态的信息都加载完成,就开始实例化父类的对象了,这里实例化对象使用的是父类的有参构造器,并且传入一共参数为12,此时父类构造器执行时,就会将父类的属性value给赋值成12,并打印了Father(int),执行完成赋值语句,后面没有代码了,就完成了父类的构造器,并返回了父类的对象的引用(super)给子类对象,当返回给子类对象后,子类构造的代码也没有了,就返回子类对象的引用(this)给了调用构造器处,后面又用子类对象调用了f()就去执行此对象的f(),这个方法首先第一句就是调用父类的f(),这个方法将父类本身的属性value又修改为100,并打印Father.value=100,此时这句话就是控制台的第一个字符串,调用完成回归到调用处,下一句时将子类对象的value赋值了200,并打印了Child.value=200,下一句时输出value意思就是打印当前对象的value,当前对象的value值又被修改为了200,所以此时打印的时200,下一句时输出父类的value,但是父类的value之前被赋值了100,所以此时打印的是100。

    6、final

    final 表示最终的。

    修饰类,表示该类不能被继承

    修饰方法,表示该方法不能被重写

    修饰属性,表示常量,值一旦确定不可改

    class F{ public final String STR="bjsxt is very good"; //最终的方法 public final void test(){ System.out.println("f-->test()"); } } //最终的类 final class C extends F{ //此方法不能别重写 public void test(){ System.out.println("c-->test()"); } */ } /* class D extends C{ }*/
    Processed: 0.014, SQL: 9