Java基础--封装、继承、多态

来源:互联网 发布:mysql 登录失败设置 编辑:程序博客网 时间:2024/05/21 20:42

第一讲 封装

一、对象的封装

1、概念        封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。2、 好处        a)将变化隔离。        b)便于使用。        c)提高重用性。        d)调高安全性。3、 原则        a)  将不需要对外提供的内容都隐藏起来。        b)  把属性都隐藏,提供公共方法对其访问。4、 封装的表现形式之一——private(私有)        private关键字:权限修饰符;用于修饰类中的成员(成员变量,成员函数);私有只在本类中有效。 常用之一:        将成员变量私有化,对外提供对应的setget方法对其进行访问。提高对数据访问的安全性。        如:我有一个人对象,而年龄这一属性我不想被对象访问,我就可以将其设为private

2、定义一个类封装它的name,age属性

class Person{    private Person(){}    private String name = "tsz";    private int age;    private static  String country = "cn";    Person(String name,int age)    {        this.name = name;        this.age = age;    }    public void setName(String name)    {        this.name = name;    }    public String getName()    {        return name;    }    public void speak()    {        System.out.println(this.name+"..."+this.age);    }    public static void  showCountry()    {        System.out.println("country="+Person.country);//静态的可以类名直接调用        Person.method();    }    public static void method()    {        System.out.println("method run");    }}class  PersonDemo{    public static void main(String[] args)     {        Person p = new Person("zhangsan",20);        p.setName("lisi");        new Person();    }}/*Person p = new Person("zhangsan",20);该句话都做了什么事情?1,因为new用到了Person.class.所以会先找到Person.class文件并加载到内存中。2,执行该类中的static代码块,如果有的话,给Person.class类进行初始化。3,在堆内存中开辟空间,分配内存地址。4,在堆内存中建立对象的特有属性。并进行默认初始化。5,对属性进行显示初始化。6,对对象进行构造代码块初始化。7,对对象进行对应的构造函数初始化。8,将内存地址付给栈内存中的p变量。*/

3、注意

private :私有,权限修饰符:用于修饰类中的成员(成员变量,成员函数)。私有只在本类中有效。将name私有化以后,类以外即使建立了对象也不能直接访问。但是人应该有年龄,就需要在Person类中提供对应访问age的方式。*注意:私有仅仅是封装的一种表现形式。之所以对外提供访问方式,就因为可以在访问方式中加入逻辑判断等语句。对访问的数据进行操作。提高代码健壮性。

二、构造函数的详细解读
1、构造函数

1、 特点:        a) 函数名与类名相同。        b) 不用定义返回值类型。        c) 不可以写return语句。2、 作用:        给对象进行初始化。3、构造函数的小细节:        当一个类中没有定义构造函数时,那么系统就会默认给该类加入一个空参数的构造函数。当在类中自定义了构造函数后,默认的构造函数就没有了。4、构造函数和一般函数在写法上有不同。在运行上也有不同:        构造函数式在对象一建立就运行,给对象初始化。而一般方法是对象调用才执行,给是对象添加对象具备的功能。一个对象建立,构造函数只运行一次。而一般方法可以被该对象调用多次。5、什么时候定义构造函数?        当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。6、构造代码块       作用:给对象进行初始化。对象一建立就运行,而且优先于构造函数运行。和构造函数的区别:       构造代码块是给所有对象进行初始化。       而构造函数是给对应的对象初始化。构造代码块中定义的是不同对象共性的初始化内容。

2、构造函数实现

class Person{    private String name;    private int age;    /*    构造代码块。    作用:给对象进行初始化。    对象一建立就运行,而且优先于构造函数执行。    和构造函数的区别:    构造代码块是给所有对象进行统一初始化,    而构造函数是给对应的对象初始化。    构造代码快中定义的是不同对象共性的初始化内容。    */    {        //System.out.println("person code run");//构造代码块        cry();    }    Person()/*构造函数*/    {        System.out.println("A: name="+name+",,age="+age);    }    /*构造函数*/    Person(String n)    {        name = n;        System.out.println("B: name="+name+",,age="+age);        //cry();    }    /*    public void setName(String n)    {        name  = n;    }    public String getName()    {        return name;    }    */    Person(String n,int a)    {        name = n;        age = a;        System.out.println("C: name="+name+",,age="+age);    }    public void cry()    {        System.out.println("cry......");    }}class  PersonDemo2{    public static void main(String[] args)     {        Person p1 = new Person();        Person p2 = new Person("lisi");     }}

第二讲 继承

一、继承(extends)
1、继承概述

(1)继承的体系结构:就是对要描述的事物进行不断的向上抽取,就出现了体系结构。要了解这个体系结构中最共性的内容,就看最顶层的类。要使用这个体系的功能,就用最底层的类创建对象。(2)继承的好处:A:继承的出现,提高了代码的复用性。B:继承的出现,让类与类之间产生了关系,extends来表示,这个关系的出现,为后面我们讲面向对象的第三个特点多态打下了基础。(3)特点A:java只支持单继承(其实确切的说是java对多继承进行了优化,避免了安全问题)。B:java支持多重(层)继承。(4)注意:A:子类可以直接访问父类中的非私有的属性和行为。B:不要仅为了获取其他类中部分功能而去继承。C:类与类之间要有所属( " is a " )关系,xx1是xx2的一种。如何判断A和B是否有继承关系?A如果继承B,那么就可以说A是B的一种。

2、继承的实例
举例:将学生和工人的共性描述提取出来,单独进行描述,只要让学生和工人与单独描述的这个类有关系,就可以了。

class Person{    String name;    int age;}class Student extends Person{        void study()    {        System.out.println("good study");    }}class Worker extends Person{    void work()    {        System.out.println("good work");    }}class ExtendsDemo {    public static void main(String[] args)     {        Student s = new Student();        s.name = "zhagnsan";    }}

3、继承后子父类之间成员的关系
(1)成员变量

class Fu{    int num = 5;}class Zi extends Fu{    int num = 20;    public void show() {        int num = 30;        System.out.println("num:"+num);        //当局部变量和成员变量重名的时候用this来区分        System.out.println("this num:"+this.num);        //当子类和父类出现了同名变量,用super来区分        System.out.println("father num:"+super.num);    }}总结:在一个类中如果方法中的局部变量和方法外的成员变量重名,那么如果在方法内输出这变量,就是方法自己的变量里的值,想要区分要用this,加上this.就是输出成员变量的值在子父类中如果出现成员变量重名的时候,在子类输出会输出自己的变量里的值,想要区分要用super,加上super.就是输出父类里变量的值    thissuper的区分:      **this代表本类对象的引用    super本类对象父类的引用。      **this可以用于区分局部变量和成员变量同名的情况。    super可以用于区分子类和父类成员变量同名的情况。      **一般,子类中不会出现和父类同名的成员变量。面试可能问到。

(2)成员方法

class Fu {    public void show() {        System.out.println("fu show");    }    public void method() {}}class Zi extends Fu{    public void show(){        System.out.println("zi show");    }}子类中存在和父类成员方法同名的这种现象,叫做重写,复写,覆盖。重写(override)和重载(overload)的区别:重载的特点:    **在同一类中。    **方法名相同,参数列表不同。重写的特点:    **要有继承关系。在子父类中    **方法的声明相同。(方法名和参数列表都相同)        ***覆盖时,子类方法权限一定要大于等于父类方法权限        父类的权限不能是私有的        ***静态只能覆盖静态。

(3)构造方法

class Fu{    Fu(){}    Fu(int age){                System.out.println("father age:"+age);    }}class Zi extends Fu{    Zi(){        this(40);        System.out.println("son");    }    Zi(int age){            super();        System.out.println("son age:"+age);    }}Zi z = new Zi();  Zi z = new Zi(30);总结:子类中所有的构造方法默认都会访问父类中空参数的构造方法。    **因为每一个构造方法的第一行都有一条默认的语句super();      当父类中没有空参数的构造方法时,子类的构造函数必须通过this      或者super语句指定要访问的构造方法。或者手动提供无参构造方法。      this(...):调用本类中的构造方法      super(...):调用父类中的构造方法构造方法用于创建对象,并进行初始化.建议如果你写了有参的构造函数,也要把空参的构造函数再手动加上否则你定义了有参的构造函数,空参的系统就不会再给了你这样创建对象的时候就会报错Person p = new Person();//这句话是会去找空参的构造函数 class Person{        Person(){}    Person(int age){        this.age = age;    }    Person(int age,String name){        this(age);        //this.age = age;        this.name = name;    } }      //Person p =new Person();  //系统默认给出无参构造      //当你手动给出构造方法后,系统就不会再给出默认的空的构造方法。      手动无参数,如果你想给属性赋值或者做一些初始化,无参你别删不就行了吗。    class Demo{        private String name;        Demo(){}        public void setName(String name){            this.name = name;        }        public String getName(){            return name;        }    }

4、final可以用来修饰什么呢?

(1)final可以用来修饰类:被fainl修饰的类不能被继承。(2)final可以用来修饰成员方法:被final修饰的成员方法不能被重写。(3)final可以用来修饰变量:被final修饰的变量为常量,值不能被修改。(4)被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。    当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。    而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成。    单词间通过_连接。(5)内部类定义在类中的局部位置上是,只能访问该局部被final修饰的局部变量。   常量的命名规范:要求大写。   final double PI = 3.14;   final修饰的变量可以在声明的时候直接赋值,还可以在构造方法可以给final修饰的变量赋值。实例:class Demo{    final int x = 3;    public static final double PI = 3.14;    final void show1()    {}    void show2()    {        final int y = 4;        System.out.println(3.14);    }}class SubDemo extends Demo{    //void show1(){}}class FinalDemo {    public static void main(String[] args)     {        System.out.println("Hello World!");    }}

第三讲 多态

1、多态的概述
多态:可以理解为事物存在的多种体现形态。

(1)某一类事物的多种存在形态。方法重载(静态多态)方法重写(动态多态,对象多态)(2)对象多态的前提A:类与类(或接口)要有继承(或实现)关系。B:一定要有方法的重写(覆盖)。C:一定要有父类或者接口的引用指向子类的对象。(3)多态的好处    多态的出现大大的提高程序的扩展性。(4)多态的弊端:    提高了扩展性,但是只能使用父类的引用访问父类中的成员。

2、多态的基本运用

abstract class Animal{    abstract void eat();}class Cat extends Animal{    public void eat()    {        System.out.println("吃鱼");    }    public void catchMouse()    {        System.out.println("抓老鼠");    }}class Dog extends Animal{    public void eat()    {        System.out.println("吃骨头");    }    public void kanJia()    {        System.out.println("看家");    }}class Pig extends Animal{    public void eat()    {        System.out.println("饲料");    }    public void gongDi()    {        System.out.println("拱地");    }}class DuoTaiDemo {    public static void main(String[] args)     {        //Cat c = new Cat();//创建cat对象        //c.eat();        /*        Cat c1 = new Cat();        function(c1);//函数的参数是animal的子类对象        function(new Dog());        function(new Pig());        */        //Animal c = new Cat();        //c.eat();        function(new Cat());//直接传匿名对象    }    public static void function(Animal a)//Animal a = new Cat();    {        a.eat();        //a.catchMouse();    }    /*    public static void function(Cat c)//    {        c.eat();    }    public static void function(Dog d)    {        d.eat();    }    public static void function(Pig p)    {        p.eat();    }    */}

3、继承重写是多态的一种表现

class Fu{    static int num = 5;    void method1()    {        System.out.println("fu method_1");    }    void method2()    {        System.out.println("fu method_2");    }    static void method4()    {        System.out.println("fu method_4");    }}class Zi extends Fu{    static int num = 8;    void method1()    {        System.out.println("zi method_1");    }    void method3()    {        System.out.println("zi method_3");    }    static void method4()    {        System.out.println("zi method_4");    }}class  DuoTaiDemo4{    public static void main(String[] args)     {        //以左边为主//      Fu f = new Zi();////      System.out.println(f.num);//结果是父类的num=5////      Zi z = new Zi();//      System.out.println(z.num);        //f.method1();        //f.method2();        //f.method3();        Fu f = new Zi();        System.out.println(f.num);//父类的num        f.method4();//静态 的情况都要看左边,如果非静态看右边运行Zi        Zi z = new Zi();        z.method4();    }}

4、多态中成员的特点

Fu f = new Zi()A、非静态方法在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。在运行时期:参阅对象所属的类中是否有调用的方法。简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。B、成员变量:编译和运行都看FuC:静态方法:编译和运行都看Fu。举例: 动物的例子: 向上转型 Animal a = new Cat(); a.eat(); //a.catchMouse();向下转型Cat c = (Cat)a;c.eat();c.catchMouse();//向上转型Animal a = new Dog();//向下转型 转换异常//Cat c = (Cat)a;Dog d = (Dog)a;总结:无论是向上转型还是向下转型,变化的都是子类对象,绝对不能把父类对象强转为子类类型
0 0
原创粉丝点击