天天看点

面向对象之多态、封装

java面向对象三大特性:继承、多态、封装

多态

1、一个事物多种形态

2、多态体现在类的继承和接口的实现

3、最终体现形态为父类引用指向子类对象;父类的引用只能调用父类有的成员,对子类新增的内容不可见

4、调用方式:

成员变量:编译运行均看父类

成员方法:编译看父类,运行看子类

public class PolyDemo01 {
	public static void main(String[] args) {
		Person p = new Person();
		System.out.println(p.name);
		p.eat();
		//父类引用指向子类对象
		Person p1 = new Student();
		System.out.println(p1.name);
		//此处的调用的eat是子类的方法
		p1.eat();
	}
}
class Person{
	String name = "小头爸爸";
	String gender;
	
	void eat() {
		System.out.println("父类方法-吃饭呢");
	}
}
class Student extends Person{
	String name = "大头儿子";
	int id = 1234;
	void eat() {
		System.out.println("子类方法-吃饭呢");
	}
	void study() {
		System.out.println("子类方法-学习呢");
	}
}
           

转型

1、基本数据类型

小范围–>大范围:向上转型,自动

大范围–>小范围:向下转型,需要强制转换

2、引用数据类型

小范围–>大范围:向上转型,自动

大范围–>小范围:向下转型,需要强制转换

注意:多态前提下,父类引用指向子类对象,父类引用只能调用父类的成员,如果想要调用子类新增的成员,需要强制向下转型

封装

3、引用类型转型时,可以与instanceof一起使用,预防类型转换异常

//判断p1是否是Student类型
if(p1 instanceof Student) {
//将父类引用p1转换成Student类型
Student p2 = (Student)p1;
//转换后可以调用子类新增的成员
p2.study();
System.out.println(p2.id);
}							
           

封装

1、隐藏内部实现细节,对外提供公共的访问方式

2、封装的优点:

提供代码安全性

提供代码复用性

public class Student {
	private String name;
	private int age;
	private int id;
	
	public void setName(String name) {
		this.name=name;
	}
	public String getName() {
		return this.name;
	}
	public void setAge(int age) {
		this.age=age;
	}
	public int getAge() {
		return this.age;
	}
	public void setId(int id) {
		this.id=id;
	}
	public int getId() {
		return this.id;
	}
}
           
public class Test {
	public static void main(String[] args) {
		Student s = new Student();
		s.setName("luka");
		s.setAge(23);
		s.setId(34244);
		System.out.println(s.getName());
		System.out.println(s.getAge());
		System.out.println(s.getId());
	}
}
           

抽象abstract

1、抽象方法:

(1)被abstract修饰的方法,必须定义在抽象类中

(2)抽象方法没有方法体

2、抽象类:

(1)被abstract修饰的类

(2)抽象类不能被实例化

(3)子类必须重写父类中所有的抽象方法,才可以实例化;实现部门抽象方法的子类仍是抽象类

(4)抽象类中可以有抽象类也可以有非抽象成员

注意:abstract不能与final static private native一起使用

public abstract class SportMan {
	abstract void run();
	abstract void sleep();
	
	public void game() {
		System.out.println("运动员要参加竞赛");
	}
}
public class Runner extends SportMan{

	@Override
	void run() {
		System.out.println("短跑运动员");
		
	}

	@Override
	void sleep() {
		System.out.println("短跑运动员在休息");
		
	}
	
	public void info() {
		System.out.println("我是一名职业短跑员");
	}
	public static void main(String[] args) {
		Runner r = new Runner();
		r.run();
		r.sleep();
		r.info();
		r.game();
	}
}
           

权限修饰符

面向对象之多态、封装

1、只有public和default可以修饰类,其他只能修饰成员

2、被private修饰的方法不能被继承,不能被重写

3、protected成员,不同包下的类访问时,需要有子类继承父类

本类:
package modifier;
public class ModifierDemo01 {
	public int a = 12;
	int b = 13;
	protected int c = 14;
	private int d = 15;
	
	public void print() {
		System.out.println("public方法");
	}
	
	void print1() {
		System.out.println("default方法");
	}
	
	protected void print2() {
		System.out.println("protected方法");
	}
	
	private void print3() {
		System.out.println("private方法");
	}
	
	public static void main(String[] args) {
		ModifierDemo01 m = new ModifierDemo01();
		System.out.println(m.a);
		System.out.println(m.b);
		System.out.println(m.c);
		System.out.println(m.d);
		m.print();
		m.print1();
		m.print2();
		m.print3();
	}
}
           
同包下
package modifier;
//同包下其他类,private成员不能被访问
public class ModifierDemo02 {
	public static void main(String[] args) {
		ModifierDemo01 m = new ModifierDemo01();
		System.out.println(m.a);
		System.out.println(m.b);
		System.out.println(m.c);
		m.print();
		m.print1();
		m.print2();
	}
}
           
不同包
package object;
import modifier.ModifierDemo01;
//不同包下的非子类  只有public成员可以被访问
public class ModifierDemo03 {
	public static void main(String[] args) {
		ModifierDemo01 m = new ModifierDemo01();
		System.out.println(m.a);
		
		m.print();
	}
}
           
//不同包下的子类
package object;
import modifier.ModifierDemo01;

public class ModifierDemo04 extends ModifierDemo01{
	public static void main(String[] args) {
		//不同包下的子类,通过父类对象只能访问父类的public成员;通过子类对象可以访问public protected修饰的成员
		ModifierDemo01 m = new ModifierDemo01();
		System.out.println(m.a);
		m.print();
		System.out.println("=====================");
		ModifierDemo04 m4 = new ModifierDemo04();
		System.out.println(m4.a);
		System.out.println(m4.c);
		m4.print();
		m4.print2();
		System.out.println("=====================");
		m4.out();
	}
	//不同包下的子类成员方法可以自己访问父类public projected成员
	public void out() {
		System.out.println(a);
		System.out.println(c);
		print();
		print2();
		System.out.println("=====================");
	}
}
           

Object之toString、equals

toString

1、类中重写toString ,将对象以字符串形式输出;没有重写时,调用的是Object的toString,输出的内容是:包名+类名@地址值

==与equals

1、==:比较基本类型的数据值,引用类型的地址值

2、equals:比较基本类型的数据值;引用类型,重写后比较的是对象属性值

public class Person {
	public String name;
	public String gender;
	public int age;
	public int num;
	
	public Person() {
		
	}
	public Person(String name,String gender,int age,int num) {
		this.name=name;
		this.gender=gender;
		this.age=age;
		this.num=num;
	}
	public String toString() {
		return "姓名:"+name+"--性别:"+gender+"--年龄:"+age+"--号码:"+num;
	}
	
	public boolean equals(Object obj) {
		if(this==obj) {
			return true;
		}
		if(obj instanceof  Person) {
			return ((Person) obj).name==this.name && ((Person) obj).gender==this.gender && ((Person) obj).age==this.age && ((Person) obj).num==this.num;
		}
		return false;
	}
}