您的位置:首页 > 文旅 > 旅游 > 网络运营商有哪些_上海企业一网通办_成都网站推广经理_谷歌浏览器中文手机版

网络运营商有哪些_上海企业一网通办_成都网站推广经理_谷歌浏览器中文手机版

2024/12/23 6:22:54 来源:https://blog.csdn.net/weixin_52836217/article/details/144147523  浏览:    关键词:网络运营商有哪些_上海企业一网通办_成都网站推广经理_谷歌浏览器中文手机版
网络运营商有哪些_上海企业一网通办_成都网站推广经理_谷歌浏览器中文手机版

Java基础入门篇


三、面向对象和JVM底层分析

3.4 面向对象的三大特征

面相对象的三大特征:封转继承多态

(一)封装

“封装”(encapsulation),封装的理念是高内聚,低耦合

  • “高内聚”:封装细节,便于修改内部代码,提高代码可维护性
  • “低耦合”:简化外部调用,便于使用者使用,便于扩展和协作

封装的优点:提高代码的安全性,提高代码的复用性
封装的实现——使用访问控制符,Java是使用“访问控制符”来控制哪些细节需要封装,哪些细节需要暴露。Java中的访问控制符:private、default、protected、public,访问权限:

  • private(同一个类可用————类内友好)
  • default(不定义默认就是default,同一个类、同一个包可用————包内友好)
  • protected(同一个类、同一个包、子类可用————父子友好、包内友好)
  • public(同一个类、同一个包、子类、所有类可用————全局友好)

若protected——若父类和子类“在同一个包中”,子类可以访问父类的protected成员,也可以访问父类new创建对象的protected成员。若protected——若父类和子类“不在同一个包中”,子类可以访问父类的protected成员,不可以访问父类new创建对象的protected成员。

package BasicJava.encapsulation.a;/**   测试封装*/
public class Person {private int testPrivate;int testDefault;protected int testProtected;public int testPublic;public void test(){System.out.println(this.testPrivate);}}
package BasicJava.encapsulation.a;
/**   测试封装*/// 同一个包内的不同类
public class Student {public void study(){Person p = new Person();// System.out.println(p.testPrivate); // 无权访问System.out.println(p.testDefault);System.out.println(p.testProtected);System.out.println(p.testPublic);}
}// 同一个包内具有继承关系的类
class Student2 extends Person{public void study(){Person p = new Person();// System.out.println(p.testPrivate); // 无权访问System.out.println(p.testDefault);System.out.println(p.testProtected);System.out.println(p.testPublic);}}

开发过程中封装的简单规则:

  1. 属性一般使用private,私有后提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的(注意:boolean变量的get方法是is开头的)。
  2. 方法:一些只用于本类的辅助方法可以用private修饰,希望其他类调用的方法可以用public修饰。
package BasicJava.encapsulation.b;import BasicJava.encapsulation.a.Person;
/**   测试封装*/
public class Child extends Person {public void play(){Person p = new Person();// 此时由于是不同包的继承,所以不能使用父类对象的protected修饰的属性/方法//System.out.println(p.testProtected);System.out.println(super.testProtected); // 但是可以访问父类的protected成员}
}
package BasicJava.encapsulation.b;/*
*   测试封装的简单规则*/
public class User {private int id;private String name;private boolean man;// private类型的属性通过get/set方法调用public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public boolean isMan() {return man;}public void setMan(boolean man) {this.man = man;}
}
package BasicJava.encapsulation.b;
/**   测试封装的简单规则*/
public class TestUser {public static void main(String[] args) {User u = new User();u.setId(100);u.setName("小明");u.setMan(true);System.out.println(u.getId());System.out.println(u.getName());System.out.println(u.isMan());}}

在这里插入图片描述

(二)继承

当我们不显示指定extends时,默认继承自父类java.lang.Object类,继承的作用:

  1. 代码复用,更加容易实现类的扩展,

  2. 方便建模,子类是父类的扩展

instanceof运算符是二元运算法,左边是对象,右边是类,用于判断当前对象是否是右边类或子类所创建的对象,是则返回true,反之返回false。

继承中父类又叫超类、基类,子类又叫派生类。Java中只有单继承,不像C++存在多继承,多继承会使得继承链过于复杂,系统难以维护引起混乱。Java中类没有多继承但是接口有多继承,子类继承父类,可以得到父类全部的属性和方法(除了父类的构造方法),但是不见得可以直接访问,例如父类中的私有属性/方法。

 /**   测试继承*/public static class Person{String name;int height;public void rest(){System.out.println("休息一会!");}}public static class Student extends Person{String school;public Student(String name, int height, String school){this.name = name;this.height = height;this.school = school;}public void study(){System.out.println("学习!");}}public static void testExtends(){Student s1 = new Student("小明", 175, "HBU");s1.study();s1.rest();System.out.println(s1 instanceof Student);System.out.println(s1 instanceof Person);}

在这里插入图片描述

super可以看作是堆父类对象的直接引用,可以通过super来访问父类中被子类覆盖的方法/属性。使用super调用普通方法,语句没有位置限制,可以在子类中任意使用。在一个类中,若是构造方法第一行没有调用super(…)或者this(…),那么Java默认调用super(),含义是调用父类的无参构造方法。

/*
*   使用super调用父类方法*/
public static class FatherClass{int value;void f(){value = 100;System.out.println("FatherClass's value is : " + value);}
}public static class ChildClass extends FatherClass{int value;int age;void f(){// 调用父类的普通方法super.f();value = 200;System.out.println("ChildClass's value is : " + value);System.out.println(super.value);}
}public static void testSuper(){ChildClass c1 = new ChildClass();c1.f();
}}

在这里插入图片描述

方法重写override与方法重载overload毫无关系。重写是指子类重写父类的方法可以用自身的行为替换父类的行为,重写是实现“多态”的必要条件。方法重写需要符合以下三个要点:

  1. “==”方法名、形参列表相同

  2. “≤”返回值类型和声明异常类型,子类小于等于父类

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

除了继承,**“组合”**也可以实现代码的复用,组合的核心是将父类对象作为子类的属性。组合就是在子类中new一个父类对象,然后通过对象名+属性/方法的方式使用父类。和继承相比,组合更加灵活,继承只能有一个父类,但是组合可以new多个类,使用他们的属性。对于is-a的关系建议使用“继承”(Student is a Person),对于has-a的关系建议使用“组合”(Student has a bike)。

/**   测试方法重写override*/public static  class Vehicle{public void run(){System.out.println("跑!");}public Vehicle getVehicle(){System.out.println("给你一个交通工具!");return null;}}public static class Horse extends Vehicle{@Overridepublic void run() {System.out.println("这是一匹马跑起来了!");}@Overridepublic Horse getVehicle() {return new Horse();}}public static void testOverride(){Horse h = new Horse();h.run();h.getVehicle();}

在这里插入图片描述

/**   实现组合*/public static class Car{String name;int number;Car(){System.out.println("还没初始化");}Car(String name, int number){this.name = name;this.number = number;}public void run(){System.out.println(this.name + this.number + "出发!");}}public static class Bike{// 组合就是在子类中new一个父类对象,然后通过对象名+属性/方法的方式使用父类Car c = new Car();int wheel;public Bike(int wheel, String name, int number){this.wheel = wheel;this.c.name = name;this.c.number = number;}public void letCarGo(){System.out.println(this.c.name + this.c.number + "出发!");}public void letBikeGo(){System.out.println("这是一个"+ this.wheel + "轮车,出发!");}}public static void testCombine(){Car c1 = new Car("奔驰", 1001);c1.run();Bike b1 = new Bike(3, "丰田", 1002);b1.letCarGo();b1.letBikeGo();}

在这里插入图片描述

属性/方法查找顺序,例如,查找变量h -> 查找当前类中有没有属性h -> 依次上溯每个父类 -> 查找每个父类中是否有h,直到Object -> 如果没有找到,则出现编译错误。
构造方法调用顺序,构造方法第一句总是super(…)来调用父类对应的构造方法,流程是:现象上追溯到Object类 -> 然后再次依次向下执行类的初始化块和构造方法 -> 直到当前子类为止。
静态初始化块的执行顺序和构造方法调用顺序一致。

/*
*   感受构造函数初始化顺序*/
class FatherClass2{//定义静态初始化块static{System.out.println("静态初始化块:FatherClass2");}// 无参构造器FatherClass2(){System.out.println("创建FatherClass2");}
}class ChildClass2 extends FatherClass2{//定义静态初始化块static{System.out.println("静态初始化块:ChildClass2");}ChildClass2(){// 默认情况下是调用父类的无参构造器,等同于super();System.out.println("创建ChildClass2");}
}

在这里插入图片描述

(三)多态

“多态”(polymorphism):同一个方法调用,不同对象行为完全不同
多态的要点:

  1. 多态是方法的多态,与属性无关
  2. 多态的存在要有三个必要条件(继承、方法重写、父类引用指向子类对象)
  3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法,就是多态
package BasicJava.polymorphism;
/*
*   测试多态*/
public class Animal {public void shout(){System.out.println("动物的叫声");}
}class Dog extends Animal{@Overridepublic void shout() {System.out.println("汪汪汪!");}public void seeDoor(){System.out.println("正在看门...");}
}
class Cat extends Animal{@Overridepublic void shout() {System.out.println("喵喵喵!");}public void catchMouse(){System.out.println("正在抓老鼠...");}
}

对象的转型(casting):由父类引用指向子类对象的过程中,我们称之为“向上转型”,属于“自动类型转换”。向上转型后的父类引用变量只能调用它“编译类型”的方法,不能调用它“运行时类型”的方法,这时我们需要进行强制类型转换,我们称之为“向下转型”。

package BasicJava.polymorphism;public class TestPoly {public static void main(String[] args) {animalShout(new Dog()); // 相当于Animal a = new Dog(); 属于“向上转型”animalShout(new Cat()); // 相当于Animal a = new Cat(); 属于“向上转型”// new Dog()是我们真正的类型,Animal animal是我们定义的类型,因此无法执行Dog()类中的seeDoor()方法//编译类型       运行时类型Animal animal = new Dog();animal.shout(); // 可以执行// animal.seeDoor(); //无法执行// 通过“向下转型”就可以了,这里的d其实就是animal,只不过进行了强制类型转换Dog d = (Dog)animal;d.seeDoor();// 我们可以添加一个判断来避免异常if(animal instanceof Dog){Dog d2 = (Dog)animal;d2.seeDoor();}if(animal instanceof Cat){Cat c2 = (Cat)animal;c2.catchMouse();}// 测试用不同的类进行“向下转型”的强制类型转换Cat c = (Cat)animal;c.catchMouse(); // 发现并不报错,但是这实际上只是编译时不报错,但是运行的时候会报错的// "ClassCastException: BasicJava.polymorphism.Dog cannot be cast to BasicJava.polymorphism.Cat"}static  void animalShout(Animal a){a.shout();}
}

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com