少了1秒

导航

 

21.构造方法(续):
分类:
隐式构造方法:如果在一个类中,没有手动编写构造方法,则系统会提供一个默认的无参的构造方法
显式构造方法:如果在一个类中,手动编写构造方法,则系统不会提供默认的无参的构造方法

建议:当手动编写构造方法时,建议先编写无参构造方法
22.引用数据类型
String
用户自定义类型,如:Teacher、Student

注意:引用数据类型赋值两种方式:赋值对象,赋值为null

 

小知识点:当一个对象作为另一个对象的属性
或者当一个对象中的属性是引用数据类型
23.空指针异常
java.lang.NullPointerException
出现空指针异常原因:说明该引用名称中存放的不是某个对象的地址,也就是null

解决办法:在调用某个对象中的属性或方法之前,必须保证该引用名称存放的是对象的地址

24.封装
24.1面向对象三大特征:封装、继承、多态
24.2封装
隐藏类的内部信息,不允许外部程序直接访问,而是通过方法进行操作
24.3封装的操作步骤:
第一步:将属性设置为私有的private,只能在本类中使用
private int age;
第二步:设置属性的get取值和set赋值方法
//赋值方法
public void setAge(int age){
//第三步:适当位置编写判断语句
if(age >= 0 && age <= 120){
this.age = age;
}else{
this.age = 21;
}
}

//取值方法
public int getAge(){
return age;
}

*
    编写人Person类,属性:名字、年龄、性别,通过封装完成对属性赋值和取值
*/
class Person{
    //属性
    private String name;
    private int age;
    private char sex;

    //编写所有属性的赋值方法
    public void setName(String name){
        this.name = name;
    }
    public void setAge(int age){
        //当年龄在0---120为合法的,否则为21
        if(age >= 0 && age <= 120){
            this.age = age;
        }else{
            this.age = 21;
        }
    }
    public void setSex(char sex){
        //性别只能是男或女,否则性别为女
        if(sex == '男' || sex == '女'){
            this.sex = sex;
        }else{
            this.sex = '女';
        }
    }
    //编写所有属性的取值方法
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public char getSex(){
        return sex;
    }
    
}
//编写人的测试类
class PersonTest{
    public static void main(String[] args){
        //实例化Person
        Person p = new Person();
        
        p.setName("李四");
        p.setAge(23);
        p.setSex('n');

        System.out.println("姓名:" + p.getName() + "\n年龄:" + p.getAge() + "\n性别:" + p.getSex());
    }
}

 


25.this关键字
this代表当前这个对象,也就是说当前谁调用该方法则this代表就是谁
this关键字可以访问当前类中的属性、方法、也可以访问构造方法
注意:

1.当访问本类中的非静态方法和属性时,默认前面添加this.
2.当访问本类中的构造方法时,必须编写在构造方法中,并且是第一条语句
3.构造方法不能出现递归调用
26.参数传递
26.1基本数据类型作为参数传递----传递值
总结:当基本数据类型作为参数进行传递时,传递的是值,当有一个方法中的值发生改变,则对另一个方法中的值没有任何影响(各自是独立的)


26.2引用数据类型作为参数传递----传递地址
总结:当引用数据类型作为参数传递时,传递的是地址,当一个方法中属性的值发生改变时,对另一个方法中的属性值有影响(共用同一个地址)

27.static关键字
27.1 static关键字可以修饰属性
---该属性在方法区中开辟空间
---访问时可以使用类名.属性名称、引用名称.属性名称,当引用名称的值为null时也可以访问
如:Student.address
stu.address
stu = null;
stu.address
---与类同生死,生命周期长
---类优先于对象


27.2好处:节省空间

27.3.3static关键字可以修饰方法
注意:

1.静态方法中只能访问静态属性和方法
2.实例方法中可以访问静态的属性和方法,也可以访问实例属性和方法
3.3static关键字可以修饰代码块 ,称为静态代码块
static{

}
作用:完成静态属性赋值的

注意:1.当类被第一次载入时,静态代码块就自动执行

建议:当调用静态属性或静态方法时,使用类名

练习:
编写一个狗类,属性:名字、颜色、年龄、品种,方法:输出信息
编写一个猫类,属性:名字、颜色、年龄,方法:输出信息
编写测试类,分别创建猫和狗的对象,输出信息

 

分析:发现以上猫类和狗类中有相同的属性、方法,能否将共有的属性和方法编写一次?
-----能
解决办法:
1.将相同的属性和方法编写在单独的一个类中,称为父类
2.然后在猫和狗子类中继承父类,并编写子类中独有的属性和独有的方法

动物Animal类:
共有属性:名字、颜色、年龄
共有方法:输出信息
狗类 继承 动物类
独有属性:品种strain
猫类 继承 动物类

/第一步:编写父类Animal
class Animal{
    //属性也叫做成员变量或实例变量
    String name;
    String color;
    int age;

    //方法也叫做成员方法或实例方法
    public void show(){
        System.out.println("名字:" + name);
        System.out.println("颜色: " + color);
        System.out.println("年龄:" + age);
    }
}
//编写狗的子类并继承父类Animal
class Dog extends Animal{
    //编写独有的属性
    String strain;

    //编写show方法,输出狗的所有信息-----方法的重写
    public void show(){
        System.out.println("名字:" + name);
        System.out.println("颜色: " + color);
        System.out.println("年龄:" + age);
        System.out.println("品种:" + strain);
    }
}
//编写猫的子类并继承父类Animal
class Cat extends Animal{

}
//编写测试类
class Test{
    public static void main(String[] args){
        //创建狗的对象,输出信息
        Dog dog = new Dog();
        dog.show();  //调用子类中重写后的show方法

        System.out.println();
        //创建猫的对象,输出信息
        Cat cat = new Cat();
        cat.show();  //调用父类中的show方法
    }
}

 



28.继承
28.1好处:减少代码的冗余性
28.2面向对象有三大特征:封装,继承,多态

28.3继承画类图


28.4编写继承的代码
第一步:编写父类
第二步:编写子类
class 子类名称 extends 父类名称{

}

注意:在Java中,所有类都是从Object类继承过来的,也就是说所有类的根都是Object
class Dog{

}
//等价于
class Dog extends Object{

}

也就是说如果父类是Object则可以省略不写
28.5 方法重写(override)也叫覆盖
在子类中重写父类中的方法,必须保证子类中方法的名字与父类方法名称一致、参数列表一致、返回一致或父类方法返回类型的子类类型、修饰符不能缩小范围

注意:

1.只能重写父类的实例方法
2.私有的方法不能被重写
2.继承的注意事项
---当子类继承父类时,继承父类中属性和方法,但是父类中的私有成员(成员变量和成员方法)不能被继承,以及父类中的构造方法也不能被继承
---父类也叫做超类,基类
子类也叫做派生类
---一个类只能继承一个直接的父类,也就是说类是单根性
---类具有传递性
class A{
//2个属性,3个方法
}
class B extends A{
//独有属性1个,独有方法2个
}
class C extends B{

}
28.6.super关键字
super表示父类,必须在子类中访问父类中的属性、方法也可以访问父类中的构造方法
注意:当使用super关键字访问父类中的构造方法,则必须编写在子类构造方法中,并且是第一条语句

.this关键字
this关键字可以访问当前类中的属性、方法以及构造方法
还可以访问父类中的属性、方法

28.7.当创建子类对象,父类做了什么?
----先执行父类的构造方法,然后再执行子类相匹配的构造方法

----如果子类构造方法中没有指明调用父类哪个构造方法,则默认调用父类的无参构造方法
----如果子类构造方法中指明调用父类哪个构造方法,通过super()或super(name,color,age),则调用父类相匹配的构造方法
29.多态

多个对象调用同一个方法,则结果不同

class Person{
    //属性
    String name;
    int age;
    char sex;

    //构造方法
    public Person(){

    }
    public Person(String name,int age,char sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    //编写显示信息方法
    public void show(){
        System.out.println("姓名:" + this.name + "\n年龄:" + this.age + "\n性别:" + this.sex);
    }
}
//编写Student子类并继承Person父类
class Student extends Person{
    //编写子类独有的属性:成绩
    double score;

    //构造方法
    public Student(){

    }
    public Student(String name,int age,char sex,double score){
        super(name,age,sex);
        this.score = score;
    }

    //编写学习的独有方法
    public void study(){
        System.out.println(super.name + "正在学习面向对象编程......");
    }

    //重写显示信息方法
    public void show(){
        super.show();
        System.out.println("成绩: " + score);
    }
}
//编写Teacher子类并继承Person父类
class Teacher extends Person{
    //编写独有属性:薪资
    double salary;

    //构造方法
    public Teacher(){

    }
    public Teacher(String name,int age,char sex,double salary){
        super(name,age,sex);
        this.salary = salary;
    }

    //编写独有方法教学
    public void teach(){
        System.out.println(super.name + "正在讲面向对象编程课程。。。。。。");
    }

    //重写父类的显示信息方法
    public void show(){
        super.show();
        System.out.println("薪资:" + this.salary);
    }
}
//编写测试类
class Test{
    public static void main(String[] args){
        //创建Student对象
        /*Student s = new Student();  //没有构成多态
        s.show();  //先在学生类中找,如果没有找到则再去父类中找show方法*/

        /*Person s2 = new Student();  //就是多态:多种形态,则只能访问父类中的属性和方法,但是优先访问子类重写以后的方法
        s2.show();  //优先访问子类重写以后的方法
        //s2.study();  //出现编译错误,原因:多态不能访问子类独有的属性和方法

        System.out.println(s2.name);  //null
        System.out.println(s2.age);  //0
        System.out.println(s2.sex); //
        //System.out.println(s2.score);  //出现编译错误,原因:多态不能访问子类独有的属性和方法*/

        //父类类名 引用名称 = new 子类类名();
        /*Person p = new Student();  //构成多态
        p.show();  //优先访问重写以后的方法

        System.out.println();
        Person p2 = new Teacher();  //构成多态
        p2.show();*/

        /*Teacher t = new Teacher();  //没有构成多态
        t.show();*/
    }
}

//编写第二个测试类
class Test2{
    public static void main(String[] args){
        //Student s = new Student();  //没有构成多态
        /*System.out.println(s.name);  //null
        System.out.println(s.age);  //0
        System.out.println(s.sex); 
        System.out.println(s.score);  //0.0

        s.show();
        s.study();*/

        Person p = new Person(); //没有构成多态,注意:一般不实例化父类
        /*System.out.println(p.name);  //null
        System.out.println(p.age); //0
        System.out.println(p.sex); */
        //System.out.println(p.score); //编译错误

        //p.show();  //访问父类中的show方法

        Person person = new Student();  //构成多态,同时也是向上转型
        person.show();
        
        //必须将person引用名称转为Student类型,则才可以访问study方法
        //person.study(); //编译错误
        /*Student stu = (Student)person;  //向下转型
        stu.study();

        Teacher t = (Teacher)person;  //出现运行错误,原因:person引用中存放的是学生对象的地址,因此不能随意转为其他子类类型,建议在进行向下转型之前先进行判断,当合法进行向下转型,使用instanceof关键字
        System.out.println(t.salary);*/

        //在进行向下类型转换时可能会出现类型转换异常(java.lang.ClassCastException),进行判断
        if(person instanceof Student){
            //则强制转为学生
            Student s = (Student)person;
            s.study();
        }else if(person instanceof Teacher){
            //则强制转为教师
            Teacher t = (Teacher)person;
            t.teach();
        }
    }
}

 


29.1语法格式:
父类类名 引用名称 = new 子类类名(); //当构成多态时,只能访问父类中的属性和方法,但是优先访问子类重写以后的方法
29.2满足多态的条件:
1.必须子类继承父类
2.必须在子类中重写父类的方法
3.父类类名 引用名称 = new 子类类名();
6.3在多态中,有两种类型转换:
1.子类对象---->父类类型,称为向上转型或自动类型转换
如:Person p = new Student(); //构成多态,也是向上转型或自动类型转换

举个例子:有2个类,Father是父类,Son类继承自Father。

Father f1 = new Son();   // 这就叫 upcasting (向上转型)

// 现在f1引用指向一个Son对象

Son s1 = (Son)f1;   // 这就叫 downcasting (向下转型)


当是向上转型时则只能访问父类中的属性和方法,但是优先访问子类重写以后的方法
2.父类引用名称---->子类类型,称为向下转型或强制类型转换
Student p = (Student)p;
*****注意:

1.当是多态时,并访问子类独有的属性或方法时则必须进行向下转型
2.在进行向下类型转换时可能会出现类型转换异常(java.lang.ClassCastException),建议先进行判断,满足在进行强制类型转换
30.递归:方法自己调用自己,但是必须保证要有出口
练习:使用递归完成计算n!,如:3!= 3 * 2 * 1

 

posted on 2018-04-10 22:06  少了1s  阅读(189)  评论(0编辑  收藏  举报