面向对象的三大特征(重点)封装--继承--多态

封装

将类中的信息进行隐藏,不允许在类外部访问(高内聚【类中将信息进行高度封装】低耦合【暴露少量方法给用户使用】)
如何封装
需要用到访问修饰符来进行代码的封装。

修饰符

  • public:公开的,当前项目中的所有类中都可见
  • protected:受保护的,在同一个包下或者在子类中可见。
  • [default]:不加访问修饰词时,表示默认访问权限,同一包可见
  • private:私有的,只在当前类中可见
当前类 同一包 不同包 子类 其他类
public
protected X
[default] x X
private X X X

封装的应用
person.java

public class Person {

	private String name;
	private int age;
	
	//getter,setter:用于操作被封装的属性
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		
		return age;
	}
	public void setAge(int age) {
		//防止输入有误添加限制
		if(age>=18 && age<=50){
			this.age = age;
		}else{
			System.out.println("输入的年龄有误,年龄区间【18-50】默认18");
			this.age=18;
		}
	}
	public void show(){
		System.out.println("姓名:"+name+":"+"年龄"+age);
	}
	/**
	 * 如果num为1,表示要学习java,如果num 为2,表示要学习数据库
	 * @param num
	 */
	public void study(int num){
		if(num==1){
			studyJava();
		}else if(num==2){
			studyDB();
		}
	}
	//private 私有化方法只在类内部调用,提供了study公有方法内部封装studyDB,studyJava
	private void studyDB() {
		System.out.println(this.name+"正在学习数据库");
	}
	private void studyJava() {
		System.out.println(this.name+"正在学习java");
	}
}

TestPerson.java

public class TestPerson {

	public static void main(String[] args) {
		Person person=new Person();
		person.setName("张杰");
		person.setAge(25);
		person.show();
		person.study(2);
	}
}
/*
姓名:张杰:年龄25
张杰正在学习数据库
*/

继承

管理类和类之间的关系。减少代码的重复,可以使用继承。可以对父类进行扩展。
继承可以实现代码的重用,类是对对象的抽象,继承是对一部分代码的抽象。实现继承,需要使用一个关键字extends

继承的特点

被继承的类:父类,基类,超类
继承别的类:子类衍生类
父类的成员变量和方法可以被继承,构造器不能被继承。(名字)
继承可以实现代码的复用,降低代码的冗余
构造器不能被继承,但是可以通过super调用父类的构造器
this 和super

  • this代表当前类的对象的引用,super代表父类对象的引用
  • this 可以用于调用成员变量和方法,super 可以用于调用父类的成员变量和方法
  • this 在构造器中可以被用于调用当前类的其他构造器,必须写在第一行,super 在构造器中可以被用于调用父类的方法和成员变量。必须写在第一行。
  • this 和super 不能同时使用
    Person.java
/**
 * 被继承的类,称之为父类;基类,超类
 * @author lenovo
 *
 */
public class Person {

	private String name;
	 private int age;
	
	//构造器
	public Person(){
		
	}
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	public void show(){
		System.out.println("姓名:"+name+":"+"年龄"+age);
	}
}

Teacher.java

/**
 * 通过extends 关键字可以实现类的继承关系
 * 子类可以对父类进行扩展
 * @author lenovo
 *
 */
public class Teacher extends Person{

	double salary;//工资
	//构造器 
	/*public Teacher(){
	}*/
	/**
	 * super关键字,代表父类的对象的引用,super()表示引用父类构造器
	 * 默认情况下,子类构造器,java会在构造器中开头默认加一个super()
	 * 如果自己调用了父类的其他构造器,那么就不会调用父类的无参构造器了
	 * @param name
	 * @param age
	 * @param salary
	 */
	public Teacher(String name, int age, double salary) {
		super(name,age);
		this.salary = salary;
	}
	public void showSal(){
		System.out.println("工资"+salary);
	}

方法的重载overload :方法名相同,参数 列表不同(参数类型,参数个数,参数顺序)

方法重写

出现在继承中,overwrite 子类方法对父类方法进行扩展的情况被称之为方法的重写。
重写特点:

  • 子类重写:方法同名,同返回值类型,参数列表,访问修饰符的范围要大于等于父类访问修饰符的范围
  • 可以使用super().方法名进行调用
  • 子类一旦重写父类方法父类方法将不再使用
  • 重写的好处:可以在父类方法功能的基础 进行拓展,提高了程序的可扩展性
/**
 * 通过extends 关键字可以实现类的继承关系
 * 子类可以对父类进行扩展
 * @author lenovo
 *
 */
public class Teacher extends Person{

	double salary;//工资
	//构造器 
	public Teacher(){
	}
	/**
	 * super关键字,代表父类的对象的引用,super()表示引用父类构造器
	 * 默认情况下,子类构造器,java会在构造器中开头默认加一个super()
	 * 如果自己调用了父类的其他构造器,那么就不会调用父类的无参构造器了
	 */
	public Teacher(String name, int age, double salary) {
		
		super(name,age);
		this.salary = salary;
	}
	public void showSal(){
		
		System.out.println("工资"+salary);
	}
	public void show(){
		System.out.println("这是子类中的show方法");
		super.show();
		System.out.println("=========");
	}
}

Object类

在java中,Object l类是所有类的直接或者间接父类。顶级父类。
Object 中提供的几个方法

  • toString():将对象转换为字符串,当打印对象时,默认会调用toString 方法。自定义类型中,我们可以重写toString 方法,从而方便对象的打印
  • equals(java.lang.Object arg0)
    Demo.java
public class Demo {

	private int a;
	private String b;
	
	public Demo(){}
	public Demo(String b,int a){
		
		this.a=a;
		this.b=b;
	}
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + a;
		result = prime * result + ((b == null) ? 0 : b.hashCode());
		return result;
	}
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Demo other = (Demo) obj;
		if (a != other.a)
			return false;
		if (b == null) {
			if (other.b != null)
				return false;
		} else if (!b.equals(other.b))
			return false;
		return true;
	}
	
	/*public boolean equals(Object obj) {
		Demo d =(Demo)obj;
		if(this==obj){
			return true;
		}
		if(this.a!=d.a){
			return false;
		}else if(this.b.equals(d.b)){
			return true;
		}
		return false;
	}*/
}

TestDemo.java

public class TestDemo {

	public static void main(String[] args) {
		Demo demo=new Demo("asda",12);
		Demo demo2=new Demo("asda",12);
		System.out.println(demo==demo2);
		System.out.println(demo.equals(demo2));//默认false 重写equals后true
	}
}

多态

一个类可以多种形态。提高代码的可扩展性。
多种形态:对象的类型在编译阶段类型不固定。在运行阶段才能够确定类型

引用数据类型类型的转换

public class Test {

	public static void main(String[] args) {
		Person person=new Person("张三",18);
		Teacher teacher=new Teacher("李四",20,30000);
		
		//引用类型的类型转换,分两种情况
		//小类型转大类型---》向上转型
		//大类型转小类型----》向下转型
		
		//小类型转大类型---》向上转型
		//将子类型转换成父类型,子类型中独有的方法将不能用
		Person p=teacher;
		p.show();
		//大类型转小类型----》向下转型
		//可以使用instanceof 关键字判断类型,用于查看某个对象是否是某个类型的对象
		/*Teacher t=(Teacher)person;
		t.show();
		t.showSal();*/
		Person p2=teacher;//先向上转型
		Teacher t=(Teacher)p2;
		t.show();
		t.showSal();
		
	}
}

多态的应用

person.java

public class Person {
	private String name;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Person(){}
	
	public Person(String name){
		this.name=name;
	}
	public void show (){
		System.out.println("姓名:"+name);
	}
}

chinese.java

public class Chinese extends Person {

	private String loc;

	public Chinese() {
		super();
	}

	public Chinese(String name,String loc) {
		super(name);
		this.loc=loc;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}
	public void taiji (){
		System.out.println(this.getName()+"打了一套太极拳。。。");
	}
	
}

American.java

public class American extends Person {

	private String xinzuo;

	public American() {
		super();
	}

	public American(String name,String xinzuo) {
		super(name);
		this.xinzuo=xinzuo;
	}

	public String getXinzuo() {
		return xinzuo;
	}

	public void setXinzuo(String xinzuo) {
		this.xinzuo = xinzuo;
	}
	public void drinkCoffe(){
		System.out.println(this.getName()+"喝了一杯咖啡");
	}
}

company.java

public class Company {

	/**
	 * 招聘方法,使用多态可以解决这个问题:定义方法过多
	 */
	public void findPerson(Person person){
		System.out.println("公司招到一个新员工");
		person.show();
		//才艺表演
		if(person instanceof Chinese){
			Chinese c=(Chinese) person;
			c.taiji();
		}else if(person instanceof American){
			American a=(American)person;
			a.drinkCoffe();
		}
		
	}
}

Test.java

public class Test {
	public static void main(String[] args) {
		Company company = new Company();
		Person person=new Chinese("张杰","狗");//向上转型
		company.findPerson(person);
	}
}

总结

什么时候会发生多态?(发生多态的前提)
必须要有继承关系,
发生类型转换:向上转型,向下转型
方法调用:子类对象可以调用父类中的方法
父类对象可以调用子类的方法
多态的好处
类型在编译阶段只是父类,运行阶段可以是任意的子类型,简化方法的重载,
方便代码的扩展,

发布了23 篇原创文章 · 获赞 4 · 访问量 374

猜你喜欢

转载自blog.csdn.net/weixin_44804206/article/details/105281740