Java-8 面向对象(继承)

3.面向对象--继承

3.1继承概述

  • 多个类中存在相同的属性和行为,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承这个新定义的类即可。

    // 继承格式
    class 子类名 extends 父类名{}
      // 被继承的类叫:父类,基类,超类
    	// 继承的类:子类,派生类
    // java的继承只支持单继承(但支持多层继承), 父类中的私有成员是不能被继承的,构造方法不能被继承的,但是可以调用  Object称为所有类的祖先,如果一个类没有继承任何类,那么也默认继承Object
    
  • 一个文件定义多个类:

    • 只能有一个类使用public修饰,用public修饰的类必须和文件名相同。main方法也必须定义在这个类中,示例如下:
    package demo;
    
    public class ExtendsDemo {
    	public static void main(String[] args) {
    		
    	}
    }
    
    class Teacher{
    	
    }
    
    class Student{
    	
    }
    
    
    • 但在实战开发时候,一般一个文件定义一个类
  • 继承示例:

    package ExtendsClass;
    
    public class ExtendDemo {
    	public static void main(String[] args) {
    		Teacher t = new Teacher();
    		System.out.println(t.age);
    	}
    }
    
    class Person {
    	String name;
    	int age;
    	char gender;
    	public void eat() {
    		System.out.println("开始吃饭");
    	}
    }
    
    
    // 继承Person
    class Teacher extends Person{
    	// 定义自己特有属性
    	double salary;
    	
    }
    //继承Person
    class Student extends Person{
    	int score;
    }
    

3.2继承关系中属性赋值

package ExtendsClass;

public class ExtendDemo2 {
	public static void main(String[] args) {
		// 方式1
		Worker w = new Worker();
		w.setName("Tom");
		w.setAge(21);
		w.setGender('男');
		w.setId("123");
		// 方式2
		Worker w2 = new Worker("222", "Lucy", 20, '男');
	}
}


class People{
	String name;
	int age;
	char gender;
	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 char getGender() {
		return gender;
	}
	public void setGender(char gender) {
		this.gender = gender;
	}
}

class Worker extends People{
	String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
	public Worker() {}
	
	public Worker(String id, String name,int age,char gender) {
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.id = id;
	}
}

3.3 this和super用法

  • super:(父类中的对象)用于子类的成员和父类的成员重名时,super指代父类中的。
  • this:(本类中的对象) 用于成员变量和局部变量重名,this指代的是成员变量。
  • 在静态的方法中是不能使用this/super
  • 调用成员:
    • this.成员 -->成员变量,成员方法
    • super.成员 -->成员变量,陈孤雁方法
  • 调用构造方法:
    • this(参数): 调用本类中的构造方法
    • super(参数):调用父类中的构造方法

3.4继承中构造方法关系

  • 子类中构造方法,会调用父类中无参构造方法。如果父类中没有无参的构造方法,系统会报错,我们必须直接或间接调用父类中其他构造方法。
package ExtendsClass;

public class ExtendDemo3 {
	public static void main(String[] args) {
		FatherClass f = new FatherClass();// 父类构造方法
		SonClass f2 = new SonClass();//父类构造方法  子类构造方法
		
	}
}


class FatherClass{
	public FatherClass () {
		System.out.println("父类构造方法");
	}
}

class SonClass extends FatherClass{
	public SonClass (){
		System.out.println("子类构造方法");
	}
}
  • 直接调用父类带参构造方法
package ExtendsClass;

public class ExtendDemo3 {
	public static void main(String[] args) {
//		FatherClass f = new FatherClass();// 父类构造方法
		SonClass f2 = new SonClass();//父类构造方法  子类构造方法
		
	}
}


class FatherClass{
	public FatherClass (int a) {
		System.out.println("父类构造方法");
	}
}

class SonClass extends FatherClass{
	public SonClass (){
		super(1);
		System.out.println("子类构造方法");
	}
	public SonClass (int a){
		super(a);
	}
}
  • 间接调用父类带参构造方法
package ExtendsClass;

public class ExtendDemo3 {
	public static void main(String[] args) {
//		FatherClass f = new FatherClass();// 父类构造方法
		SonClass f2 = new SonClass();//父类构造方法  子类构造方法
		
	}
}


class FatherClass{
	public FatherClass (int a) {
		System.out.println("父类构造方法");
	}
}

class SonClass extends FatherClass{
	public SonClass (){
		this(1);
		System.out.println("子类构造方法");
	}
	public SonClass (int a){
		super(a);
	}
}
  • 注意: this() super() 调用构造方法时候,一定放在第一行。

  • 练习

package ExtendsClass;

public class ExtendDemo4 {
	public static void main(String[] args) {
		FaClass f = new FaClass();
		System.out.println(f.name);// Lucy
		f.drink();// Lucy drink
		Son1 s1 = new Son1();
		System.out.println(s1.age);
	}
}

class FaClass{
	String name = "Lucy";
	public void drink() {
		System.out.println("Lucy drink");
	}
	// 无参构造方法
	public FaClass() {
		super();
	}
	// 为父类提供有参的构造方法,在子类构造方法中调用
	public FaClass(int a) {
		super();
	}
}

class Son1 extends FaClass{
	String name = "l1";
	int age = 20;
	public void drink() {
		System.out.println("l1 drink");
	}
	// 显式调用无参构造方法
	public Son1() {
		super();
	}
	// 子类提供有参构造方法,显式调用本类中无参构造方法this();
	public Son1(int a) {
		this();
	}
	// 为子类提供无参构造方法,显式调用父类构造方法
	public Son1(String s) {
		super();
	}
	
	
}


class Son2 extends FaClass{
	String name = "l2";
	public void drink() {
		System.out.println("l2 drink");
	}
	// 为父类提供有参的构造方法,在子类构造方法中调用
	public Son2() {
		super(22);
	}
}

3.5继承中成员方法的关系

  • 先在子类中找成员方法,子类中没有去父类中找成员方法,父类中没有则报错。
package jc;

public class ExtendDemo {
	public static void main(String[] args) {
		Teacher t = new Teacher();
		t.sleep();// teacher sleep
	}
}


class Person{
	public void sleep( ) {
		System.out.println("person sleep");
	}
}

class Teacher extends Person{
	public void sleep() {
		System.out.println("teacher sleep");
	}
}

上面相当于方法的重写,它的定义是子类中出现了和父类中的方法名,参数列表,返回值类型都一样的方法,它就叫做方法重写。

  • 通过@Override注解,验证是否符合方法重写规范。
class Teacher extends Person{
	@Override
	public void sleep() {
		System.out.println("teacher sleep");
	}
}
  • 注意事项:

    • 父类中私有方法不能被重写 private修饰的。 (虽然子类可以与父类相同的私有方法,但那不叫方法的重写)
    • 子类重写父类方法,访问权限不能更低。(如父类的方法用public修饰,子类中重写方法的修饰符要大于等于父类中方法)
    • 父类中静态方法,也必须写静态方法。(静态方法不能重写,它不具备多态的特征)
  • 继承练习:判断一个坐标是否在当前区域内

// Rect.java
package com.xjk;

public class Rect {
	double width;
	double height;
	public Rect(double width, double height) {
		this.width = width;
		this.height = height;
	}
	// 构造方法
	public Rect() {
		width = 10;
		height = 10;
	}
	public double perimeter() {
		return 2*(width+height);
	}
	public double area() {
		return width*height;
	}
}

// PlainRect.java
package com.xjk;

public class PlainRect extends Rect {
	double startX;
	double startY;
	public PlainRect(double width,double height, double startX, double startY) {
		this.height = height;
		this.width = width;
		this.startX = startX;
		this.startY = startY;
	}
	public PlainRect() {
		height = 0;
		width = 0;
		startX = 0;
		startY = 0;
	}
	public boolean isInside(double x, double y) {
		if (x >=startX&&x<=(startX+width)&&y<=startY&&y>=(startY-height)) {
			return true;
		}else {
			return false;
		}
	}
}
// RectDemo.java
package com.xjk;

public class RectDemo {
	// 
	public static void main(String[] args) {
		PlainRect pr = new PlainRect(20,10,10,10);
		System.out.println("周长为:" + pr.perimeter());
		System.out.println("面积为:" + pr.area());
		boolean re = pr.isInside(25.5, 13);
		if (re){
			System.out.println("在矩形范围内");
		} else {
			System.out.println("不在矩形范围内");
		}
	}
}
原文地址:https://www.cnblogs.com/xujunkai/p/13765545.html