Java300集day05——Java面向对象进阶

1.继承的实现

package cn.sxt.oo22;

public class TestExtend {

}


class Person{
	String name;
	int height;
	public void rest(){
		System.out.println("休息一会!");
	}
}

class Student{
	String name;
	int height;
	String major;
	public void study() {
		System.out.println("学习两小时");
	}
	public void rest(){
		System.out.println("休息一会!");
	}
}

将上面的代码使用继承:

package cn.sxt.oo22;

public class TestExtend {
	public static void main(String args[]) {
		Student stu = new Student();
		stu.name = "郭川川";//调用父类的属性方法
		stu.height = 176;
		stu.rest();
		
		Student stu2 = new Student("高企",6,"挖掘机");
	}

}


class Person{//没有extends,默认继承Object
	String name;
	int height;
	public void rest(){
		System.out.println("休息一会!");
	}
}

class Student extends Person{
	
	String major;
	public void study() {
		System.out.println("学习两小时");
	}
	public Student(String name,int height,String major) {
		this.name = name;
		this.height = height;
		this.major = major;
	}
	public Student() {
		
	}
}

继承的使用要点:

1.父类也称作超类、基类、派生类等。

2.Java中只有单继承,没有像C++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。接口可以多继承

3.Java中类没有多继承,接口有多继承。

4.子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)。

5.如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。

通过a instanceof b ,判断a是否是b的对象。

2.方法的重写override

方法的重写需要符合下面的三个要点:

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

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

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

public class TestOverride {
    public static void main(String[] args) {
        Vehicle v1 = new Vehicle();
        Vehicle v2 = new Horse();
        Vehicle v3 = new Plane();
        v1.run();
        v2.run();
        v3.run();
        v2.stop();
        v3.stop();
    }
}
 
class Vehicle { // 交通工具类
    public void run() {
        System.out.println("跑....");
    }
    public void stop() {
        System.out.println("停止不动");
    }
}
class Horse extends Vehicle { // 马也是交通工具
    public void run() { // 重写父类方法
        System.out.println("四蹄翻飞,嘚嘚嘚...");
    }
}
 
class Plane extends Vehicle {
    public void run() { // 重写父类方法
        System.out.println("天上飞!");
    }
    public void stop() {
        System.out.println("空中不能停,坠毁了!");
    }
}  

3.object类的用法-

toString 方法:

类名+@+地址 

重写toString 方法

public class TestObject {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Person p = new Person("郭川川",21);
		System.out.println(p.toString());

	}

}
class Person{
	String name;
	int age;
	@Override
	public String toString(){
		return name+"年龄"+age;
	}
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
}

4.“==”代表比较双方是否相同。如果是基本类型则表示值相等,如果是引用类型则表示地址相等即是同一个对象。

 Object类中定义有:public boolean equals(Object obj)方法,提供定义“对象内容相等”的逻辑。

【示例5-6】equals方法测试和自定义类重写equals方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

public class TestEquals { 

    public static void main(String[] args) {

        Person p1 = new Person(123,"高淇");

        Person p2 = new Person(123,"高小七");     

        System.out.println(p1==p2);     //false,不是同一个对象

        System.out.println(p1.equals(p2));  //true,id相同则认为两个对象内容相同

        String s1 = new String("尚学堂");

        String s2 = new String("尚学堂");

        System.out.println(s1==s2);         //false, 两个字符串不是同一个对象

        System.out.println(s1.equals(s2));  //true,  两个字符串内容相同

    }

}

class Person {

    int id;

    String name;

    public Person(int id,String name) {

        this.id=id;

        this.name=name;

    }

    public boolean equals(Object obj) {

        if(obj == null){

            return false;

        }else {

            if(obj instanceof Person) {

                Person c = (Person)obj;

                if(c.id==this.id) {

                    return true;

                }

            }

        }

        return false;

    }

}

5.super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性 

【示例5-7】super关键字的使用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public class TestSuper01 { 

    public static void main(String[] args) {

        new ChildClass().f();

    }

}

class FatherClass {

    public int value;

    public void f(){

        value = 100;

        System.out.println ("FatherClass.value="+value);

    }

}

class ChildClass extends FatherClass {

    public int value;

    public void f() {

        super.f();  //调用父类对象的普通方法

        value = 200;

        System.out.println("ChildClass.value="+value);

        System.out.println(value);

        System.out.println(super.value); //调用父类对象的成员变量

    }

}

 6.构造方法第一句总是:super(…)来调用父类对应的构造方法。所以,流程就是:先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直到当前子类为止。

【示例5-8】构造方法向上追溯执行测试

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

public class TestSuper02 { 

    public static void main(String[] args) {

        System.out.println("开始创建一个ChildClass对象......");

        new ChildClass();

    }

}

class FatherClass {

    public FatherClass() {

                            super();//所有的构造器第一句

        System.out.println("创建FatherClass");

    }

}

class ChildClass extends FatherClass {

    public ChildClass() {

          super();

        System.out.println("创建ChildClass");

    }

}

   

7.封装 :高内聚,低耦合

封装的实现:使用访问控制符

【示例5-10】JavaBean的封装实例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public class Person {

    // 属性一般使用private修饰

    private String name;

    private int age;

    private boolean flag;

    // 为属性提供public修饰的set/get方法

    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 isFlag() {// 注意:boolean类型的属性get方法是is开头的

        return flag;

    }

    public void setFlag(boolean flag) {

        this.flag = flag;

    }

}

      下面我们使用封装来解决一下5.4.1中提到的年龄非法赋值的问题。

【示例5-11】封装的使用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

class Person {

    private String name;

    private int age;

    public Person() {

    }

    public Person(String name, int age) {

        this.name = name;

        // this.age = age;//构造方法中不能直接赋值,应该调用setAge方法

        setAge(age);

    }

     

    public void setName(String name) {

        this.name = name;

    }

    public String getName() {

        return name;

    }

    public void setAge(int age) {

        //在赋值之前先判断年龄是否合法

        if (age > 130 || age < 0) {

            this.age = 18;//不合法赋默认值18

        else {

            this.age = age;//合法才能赋值给属性age

        }

    }

    public int getAge() {

        return age;

    }

    @Override

    public String toString() {

        return "Person [name=" + name + ", age=" + age + "]";

    }

}

public class Test2 {

    public static void main(String[] args) {

        Person p1 = new Person();

        //p1.name = "小红"; //编译错误

        //p1.age = -45;  //编译错误

        p1.setName("小红");

        p1.setAge(-45);

        System.out.println(p1);

         

        Person p2 = new Person("小白"300);

        System.out.println(p2);

    }

}

8.多态:多态指的是同一个方法调用,由于对象不同可能会有不同的行为

 多态的要点:

      1. 多态是方法的多态,不是属性的多态(多态与属性无关)。

      2. 多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。

      3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。

class Animal {
    public void shout() {
        System.out.println("叫了一声!");
    }
}
class Dog extends Animal {
    public void shout() {
        System.out.println("旺旺旺!");
    }
    public void seeDoor() {
        System.out.println("看门中....");
    }
}
class Cat extends Animal {
    public void shout() {
        System.out.println("喵喵喵喵!");
    }
}
public class TestPolym {
    public static void main(String[] args) {
        Animal a1 = new Cat(); // 向上可以自动转型
        //传的具体是哪一个类就调用哪一个类的方法。大大提高了程序的可扩展性。
        animalCry(a1);
        Animal a2 = new Dog();
        animalCry(a2);//a2为编译类型,Dog对象才是运行时类型。
         
        //编写程序时,如果想调用运行时类型的方法,只能进行强制类型转换。
        // 否则通不过编译器的检查。
        Dog dog = (Dog)a2;//向下需要强制类型转换
        dog.seeDoor();
    }
 
    // 有了多态,只需要让增加的这个类继承Animal类就可以了。
    static void animalCry(Animal a) {
        a.shout();
    }
 
    /* 如果没有多态,我们这里需要写很多重载的方法。
     * 每增加一种动物,就需要重载一种动物的喊叫方法。非常麻烦。
    static void animalCry(Dog d) {
        d.shout();
    }
    static void animalCry(Cat c) {
        c.shout();
    }*/
}

9.对象的转型

10.final

 1. 修饰变量: 被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。

1

final  int   MAX_SPEED = 120;

      2. 修饰方法:该方法不可被子类重写。但是可以被重载!

1

final  void  study(){}

      3. 修饰类: 修饰的类不能被继承。比如:Math、String等。

1

final   class  A {}

 11.数组:

基本特点:

      1. 长度是确定的。数组一旦被创建,它的大小就是不可以改变的。

      2. 其元素必须是相同类型,不允许出现混合类型。

      3. 数组类型可以是任何数据类型,包括基本类型和引用类型。

数组的声明方式有两种(以一维数组为例)

1

2

type[]   arr_name; //(推荐使用这种方式)

type    arr_name[];

1. 静态初始化

      除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。

【示例7-4】静态初始化数组

1

2

int[] a = { 123 };// 静态初始化基本类型数组;

Man[] mans = { new Man(11), new Man(22) };// 静态初始化引用类型数组;

2.动态初始化

      数组定义与为数组元素分配空间并赋值的操作分开进行。

【示例7-5】动态初始化数组

1

2

3

int[] a1 = new int[2];//动态初始化数组,先分配空间;

a1[0]=1;//给数组元素赋值;

a1[1]=2;//给数组元素赋值;

3.数组的默认初始化

      数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

【示例7-6】数组的默认初始化

1

2

3

int a2[] = new int[2]; // 默认值:0,0

boolean[] b = new boolean[2]; // 默认值:false,false

String[] s = new String[2]; // 默认值:null, null

 使用for循环初始化和读取数组

增强for循环for-each是JDK1.5新增加的功能,专门用于读取数组或集合中所有的元素,即对数组进行遍历。

1. for-each增强for循环在遍历数组过程中不能修改数组中某元素的值。

2. for-each仅适用于遍历,不涉及有关索引(下标)的操作。

格式:

for (String temp : ss) {
            System.out.println(temp);
        }
//temp为临时定义的变量,ss为数组名称
发布了39 篇原创文章 · 获赞 8 · 访问量 1742

猜你喜欢

转载自blog.csdn.net/qq_42753878/article/details/98440846