美文网首页
2018-05-23 第十七天

2018-05-23 第十七天

作者: fe0180bd6eaf | 来源:发表于2018-05-23 22:03 被阅读0次

    一、面向对象九字真言:

    找对象、搞对象、搞数据。

    面向对象如何实现功能:

    创建具有各种功能的对象,然后通过对象之间的相互作用,来实现最后的需求。

    二、继承:

    语法:

    class 子类名称 extends 父类{

    }

    extends :关键字

    继承:在子类中可以直接使用父类被继承的成员。就像是自己的一样。

    扩展:重写父类的方法,自定义特有的方法。

    被继承的类:父类、基类、超类

    继承的类:子类、派生类、衍生类。

    继承的概念:子类中包含了父类的成员,并可以在子类中使用的过程。

    继承的优点:

    1:代码、类的复用。

    2:为了实现多态。

     

    缺点:1:在一定程度上打破了封装。

      2:父类中的私有的成员不能被子类继承,所有如果父类中的私有成员想被子类继承,那么必须扩大被访问的权限。就在某种程度上打破了封装性。

    继承描述的是怎样的一种关系:是一种is-a 的关系。

    不要随意的继承,只有两个类型之间的确是is-a 的关系的时候,才可以考虑使用继承。

    例1:

    /**

     * 老师教学生

     * 老师类: 姓名、年龄、性别,职称      教学生的功能  (可以让学生成绩提高)

     *

     * 学生类: 姓名,年龄,性别,成绩      学习功能   (可以让学生的成绩提高)

     *

     * 测试入口类:创建学生对象,老师对象, 打印学生信息(show 方法)  学生学习一下,老师教学一下。最后打印学生的信息show

     * @author yhl

     *

     */

    public class TestInheritance {

    public static void main(String[] args) {

    MyStudent student = new MyStudent();

    student.study();

    student.show();

    Teacher teacher = new Teacher();

    teacher.teach(student);

    student.show();

    }

    }

    class Teacher extends Person{

    private String title;

    public Teacher() {

    this("小杨老师",19,"男","初级讲师");

    }

    Teacher(String name, int age, String gender, String title) {

    setName(name);

    setAge(age);

    setGender(gender);

    setTitle(title);

    }

    void teach(MyStudent student){

    int score = student.getScore();

    student.setScore(score+1);

    System.out.println(getName() + "\t 对 "+student.getName() + "\t授课,成绩从" +score + "提升到了:"+student.getScore());

    }

    public void show(){

    System.out.println("name = "+getName() + "\tage = "+getAge() + "\tgender = "+getGender() +"\ttitle = "+title);

    }

    public String getTitle() {

    return title;

    }

    public void setTitle(String title) {

    this.title = title;

    }

    }

    class MyStudent extends Person{

    private int score;

    public MyStudent() {

    this("李雷",20,"男",90);

    }

    MyStudent(String name, int age, String gender, int score) {

    setName(name);

    setAge(age);

    setGender(gender);

    setScore(score);

    }

    void study(){

    System.out.println(getName() + "\t努力学习,成绩从 "+score ++ + "提高到了:"+score);

    }

    public int getScore() {

    return score;

    }

    public void setScore(int score) {

    this.score = score;

    }

    public void show(){

    System.out.println("name = "+getName() + "\tage = "+getAge() + "\tgender = "+getGender() +"\tscore = "+score);

    }

    }

    class Person{

    private String name;

    private int age;

    private String gender;

    public Person() {

    }

    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 String getGender() {

    return gender;

    }

    public void setGender(String gender) {

    this.gender = gender;

    }

    }

    例2:

    import com.bjsxt.util.MyUtil;

    //猫抓老鼠

    //猫和老鼠都有智商的属性  名字的属性 

    //猫:抓老鼠

    //老鼠:逃跑,死亡

    //展示信息的功能

    public class TestTomAndJerry {

    public static void main(String[] args) {

    Cat cat = new Cat(MyUtil.getRandomNumber(20, 101), "TOM");

    Mouse mouse = new Mouse(MyUtil.getRandomNumber(0, 90), "JERRY");

    cat.show();

    mouse.show();

    cat.catchMouse(mouse);

    }

    }

    class Cat extends Animal{

    public Cat() {

    }

    public Cat(int iq, String name) {

    setIq(iq);

    setName(name);

    }

    public void catchMouse(Mouse mouse){

    if(this.getIq() > mouse.getIq()){

    System.out.println(getName() + "\t抓住了 "+mouse.getName());

    mouse.die();

    }else{

    System.out.println(getName() + "\t没有抓住 "+mouse.getName());

    mouse.run();

    }

    }

    }

    class Mouse extends Animal{

    public Mouse() {

    }

    public Mouse(int iq, String name) {

    setName(name);

    setIq(iq);

    }

    public void run(){

    System.out.println(getName() + "\t逃跑了");

    }

    public void die(){

    System.out.println(getName() + "\t 被抓住了,挂了!");

    }

    }

    class Animal{

    private int iq;

    private String name;

    public int getIq() {

    return iq;

    }

    public void setIq(int iq) {

    this.iq = iq;

    }

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    public void show(){

    System.out.println("name = "+name + "\tiq = "+iq);

    }

    }

    java只支持单重继承。

    解释:java 规定不允许一个类有多个直接的父类,只能有一个直接的父类。

    但是c++ 是允许一个类有多个直接的父类的。

    直接多继承的隐患:如果多个父类中存在同名的方法,可能子类在使用父类的同名的方法的时候,存在语义上冲突问题。

    //间接的多重继承

    class A extends B{

    }

    class B extends C{

    }

    不支持多重继承的缺点:扩展类的时候不如支持多重直接继承方便。

    优点:去掉了c++ 直接多重继承的安全隐患。

    父类的哪些成员可以被继承:

    1:子类父类在同一个包下。

    除了私有的成员,都可以被子类继承。

    2:子类父类不在同一个包下

    私有的,默认的,都不能被子类继承。

    Public、protected 的可以被子类继承。

    注意:1:构造方法不能被继承。

    2:静态的成员能不能被继承:

    静态成员可以被子类继承,只要访问的权限够即可。

    被子类继承的静态的成员,可以使用父类的名称调用,也可以使用子类的名称直接调用访问。

    三、Object类

    java.lang.Object

    public class Object类

    Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。

    所有类的祖宗。 

    在java 中所有的类  除了 Object 类都直接的或者间接的继承了 Object类。

    除了Object 类 的类都是 Object 类的子类。

    如果一个类没有显式的继承任何的类,那么该类将被隐式的继承Object类。是Object类的直接的子类。

    Object 类的9个方法:

    clone(): 复制对象的。

    getClass():返回对象的大 Class 对象。

    equals(): 比较两个对象是否相等。

    finalize():垃圾回收被调用的方法。

    toString(): 得到当前对象的字符串表示形式。

    hashCode():得到对象的哈希码。

    notify():唤醒线程。

    notifyAll():唤醒所有的线程。

    wait():让线程等待。

    四、方法的重写

    方法的重载:overload

    在同一个类的内部,方法名字相同,参数列表不同,与返回类型无关的方法。

    方法的重写:override  overwrite  覆盖

    前提条件:存在继承。在子类中重写父类的方法。

    为什么需要重写:子类对象觉得父类中继承的方法不能满足自身的需求了。需要重新定义该方法。就可以在子类中对父类中的被继承的下来的方法进行重写。

    如何重写:[权限修饰符] 返回类型  方法名字(参数列表)...(抛出异常)...{方法体}

    1:权限修饰符:子类必须比父类更加的无私。

    子类重写父类的方法,子类中的方法被访问权限必须要大于等于父类的。

    2:返回类型:

    如果是基本数据类型,那么必须一致。

    如果是引用数据类型,那么子类中的方法的返回类型可以是父类的返回类型的子类型。

    3:方法名字:必须一致。

    4:参数列表:必须一致。不一致就是重载。

    5: 方法抛出的异常类型列表:方法执行的时候可能引发的问题。  子类引发的问题必须小于等于父类的。子类抛出的异常类型必须小于等于父类的。

    6:方法体:不一致。

    注意:静态方式是否可以重写?

    不能重写。静态的方法可以被子类继承,不能被子类重写。

    五、super:

    作用:

    1:在子类中访问父类的被继承的成员。当子类和父类的成员存在语义上的冲突的时候,需要用super.来定位访问的父类的成员。

    2:在子类中的构造方法的第一句,来调用父类的构造方法.

    解释:在调用子类的构造方法的时候,父类的构造方法会优先执行,然后在执行子类的构造方法。

    这个功能是由super 来完成的。

    注意:在每个子类的构造方法的第一句,都必须显式的或者隐式的通过super 调用父类的构造方法。

    隐式调用只能是调用父类的默认的无参的构造方法。super();

    如果一个父类没有默认无参的构造方法。那么必须使用super显式调用父类的构造方法。

    通过这样的语言机制,保证了父类的构造方法先执行完毕,然后再执行子类的构造方法的内容。

    通过super 来访问父类的构造方法。执行父类构造方法的意义在于:对父类实例成员进行初始化。

     

    通过在子类构造方法第一句使用super 调用父类的构造方法。

    this 调用构造方法也是第一句。两句代码不冲突,因为 this 调用的构造方法的第一句 就是调用的super();有了this 调用构造方法就不能再有super 调用父类的构造方法。

    六、生成子类对象的过程:

    类中包含的内容:成员变量、成员方法、构造方法、构造块、静态块。

    //生成一个子类对象的时候,那么父类中的静态块,构造块,构造方法,以及子类中的静态块,构造块,构造方法的一个执行的顺序。

    1:先执行父类的静态代码块,然后是子类的静态代码块。

    先加载父类,然后再加载子类。

    2:父类的构造块,父类 的构造方法

    父类的实例成员进行初始化。

    3:子类的构造块,子类的构造方法。

    子类的实例成员进行初始化。

    生成子类对象的过程描述:

    1:类加载

    按照整个子类的继承的体系,从上到下从最上层的父类,到最底层的子类,进行类加载。

    进行父类加载:对父类的静态成员初始化。执行父类的静态块。

    最后加载子类:对子类中的静态成员进行初始化,执行子类的静态块。

    2:先对最上层的父类的实例成员进行空间的分配,默认初始化,声明处的赋值,构造块,构造方法。

    3:中间可能有多个继承的层次,从上到下都进行 [如上] 的执行的步骤。

    4:最后对子类的实例成员进行空间的分配,默认初始化,声明赋值,构造块。构造方法。

    七、toString方法

    public String toString():返回该对象的字符串表示。

    通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。

    Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:

    getClass().getName() + '@' + Integer.toHexString(hashCode())

    返回:该对象的字符串表示形式。

    public String toString() {

            return getClass().getName() + "@" + Integer.toHexString(hashCode());

    }

    getClass().getName():得到当前对象的包名+类名的字符串表示形式。

    Integer.toHexString(hashCode()):得到当前对象的内存地址并转换为16进制形式的字符串。

    import com.bjsxt.util.MyUtil;

    public class TestToString {

    public static void main(String[] args) {

    Girl girl = new Girl(17, MyUtil.getRandomNumber(60, 121), "婷婷");

    //底层girl 调用 toString 方法。如果子类没有重写toString 那么将调用父类Object 的toString 方法。

    //如果想得到自定义的对象的字符串表示形式,那么需要重写toString 方法。

    System.out.println(girl);

    }

    }

    class Girl{

    private int age;

    private int iq;//[60~120]

    private String name;

    Girl(int age, int iq, String name) {

    super();

    this.age = age;

    this.iq = iq;

    this.name = name;

    }

    @Override

    public String toString() {

    return "Girl [age=" + age + ", iq=" + iq + ", name=" + name + "]";

    }

    }

    八、instanceof

    instanceof:java 的一个运算符 ,一个关键字。

    作用:判断某个对象是否是某种类型的实例。

    语法形式:对象instanceof 类型

    返回值:boolean值,如果 左边的对象是右边类型的实例。那么返回 true ,否则返回 false。

    结论:子类对象永远是父类类型的实例。父类对象不是子类类型的实例。

    注意:左边对象的类型必须和右边类型存在继承关系才可以使用instanceof 进行判断。

    /**

     * 定义一个父类:Shape 形状  属性,面积 s,周长 length。 重写Object toString 方法。 定义两个方法,一个求面积,一个求周长。 return 0  就是为了被覆盖的。

     * 矩形,width ,height, 重写 父类的求面积 ,和周长的方法。构造方法,2个 有参 和 无参。对成员变量提供访问器和修改器。 getter setter。

     * 圆,继承 Shape。 半径 radius。 重写父类的求面积和周长的方法。 构造方法,2个 有参 和 无参。对成员变量提供访问器和修改器。 getter setter。

     * 定义测试类,生成一个矩形的对象,调用有参的构造方法。 求该矩形的面积和周长。 最后调用toString 方法即可。

     * 同样生成一个圆的对象。 面积周长。toString  Round Circle  Rectangle

     *

     */

    public class TestShape {

    public static void main(String[] args) {

    Rectangle rect = new Rectangle(10, 10);

    rect.getArea();

    rect.getLength();

    System.out.println(rect);

    Round round = new Round(10);

    round.getArea();

    round.getLength();

    System.out.println(round);

    System.out.println(rect instanceof Rectangle);//true

    System.out.println(round instanceof Round);//true

    System.out.println(rect instanceof Shape);//true

    System.out.println(new Shape() instanceof Rectangle);//false

    System.out.println(rect instanceof Object);//true

    }

    }

    class Shape{

    //形状的面积

    private double area;

    //形状的周长

    private double length;

    public double getArea(){

    return 0;

    }

    public double getLength(){

    return 0;

    }

    public void setArea(double area) {

    this.area = area;

    }

    public void setLength(double length) {

    this.length = length;

    }

    @Override//重写检测  后面的方法必须是重写父类的方法,不是重写就编译错误。

    public String toString() {

    return "Shape [area=" + area + ", length=" + length + "]";

    }

    }

    class Rectangle extends Shape{

    private int width;

    private int height;

    public Rectangle() {

    }

    public Rectangle(int width, int height) {

    super();

    this.width = width;

    this.height = height;

    }

    public int getWidth() {

    return width;

    }

    public void setWidth(int width) {

    this.width = width;

    }

    public int getHeight() {

    return height;

    }

    public void setHeight(int height) {

    this.height = height;

    }

    @Override

    public double getArea() {

    //计算面积,并将面积的结果赋值给父类的面积变量

    int area = width * height;

    setArea(area);

    return area;

    }

    @Override

    public double getLength() {

    int length = width + height << 1;

    setLength(length);

    return length;

    }

    }

    //圆,继承 Shape。 半径 radius。 重写父类的求面积和周长的方法。 构造方法,2个 有参 和 无参。对成员变量提供访问器和修改器。 getter setter。

    class Round extends Shape{

    private int radius;

    public Round() {

    }

    Round(int radius) {

    super();

    this.radius = radius;

    }

    public int getRadius() {

    return radius;

    }

    public void setRadius(int radius) {

    this.radius = radius;

    }

    @Override

    public double getLength() {

    double length = 2 * Math.PI * radius;

    setLength(length);

    return length;

    }

    @Override

    public double getArea() {

    double area = Math.PI * radius * radius;

    setArea(area);

    return area;

    }

    }

    相关文章

      网友评论

          本文标题:2018-05-23 第十七天

          本文链接:https://www.haomeiwen.com/subject/vdbdjftx.html