JAVA300集——面向对象编程-封装-继承-多态

本章技能点列表

在这里插入图片描述

在这里插入图片描述

面向对象的三大特征

1. 继承 inheritance
• 子类 父类
• 子类可以从父类继承属性和方法
• 子类可以提供自己单独的属性和方法

2. 封装/隐藏encapsulation
• 对外隐藏某些属性和方法
• 对外公开某些属性和方法

3. 多态 polymorphism
• 为了适应需求的多种变化, 使代码变得更加通用!
• 面向过程只有封装性(功能的封装, 而没有数据的封装) , 没有继承和多态

隐藏/封装(encapsulation)

  1. 为什么需要封装? 封装的作用和含义?
    • 我要看电视, 只需要按一下开关和换台就可以了。 有必要了解电视机内部的结构吗? 有必要碰碰显像管吗?

  2. 隐藏对象内部的复杂性, 只对外公开简单的接口。 便于外界调用, 从而提高系统的可扩展性、 可维护性。

  3. 我们程序设计要追求“高内聚, 低耦合” 。
    • 高内聚 : 就是类的内部数据操作细节自己完成, 不允许外部干涉;
    • 低耦合 : 仅暴露少量的方法给外部使用

使用访问控制符, 实现封装

  1. 成员(成员变量或成员方法) 访问权限共有四种:
    public 公共的:可以被项目中所有的类访问。 (项目可见性)
    protected 受保护的:可以被这个类本身访问; 同一个包中的所有其他的类访问; 被它的子类(同一个包以及不同包中的子类) 访问
    default/friendly 默认的/友好的(包可见性):被这个类本身访问; 被同一个包中的类访问。
    private 私有的:只能被这个类本身访问。 (类可见性)

  2. 类的访问权限只有两种:
    public 公共的:可被同一项目中所有的类访问。 (必须与文件名同名)
    default/friendly 默认的/友好的:可被同一个包中的类访问。

在这里插入图片描述

  1. 类的属性的处理:
    • 一般使用private. (除非本属性确定会让子类继承)
    • 提供相应的get/set方法来访问相关属性。这些方法通常是public, 从而提供对属性的读取操作。
    (注意: boolean变量的get方法是用: is开头!)
    • 一些只用于本类的辅助性方法可以用private,
    • 希望其他类调用的方法用public
package cn.sxt.oo2;

public  class  Human {
	private  int age ;
	String  name;			//可以被本包下面的类访问
	protected   int  height;   
	
	
	public  void   sayAge(){
		System.out.println(age);
	}
}
package cn.sxt.oo2;

/**
 * 测试封装
 *
 */
public class TestEncapsulation {
	public static void main(String[] args) {
		Human  h = new Human();
//		h.age = 13;
		h.name = "高";
		h.height = 230;
		
		Person4  p4 = new Person4();
//		p4.age = 14;
		p4.setAge(-14);
		System.out.println(p4.getAge());
	}
}


class   Boy  extends Human {
	public  void  sayHello(){
//		System.out.println(age);		//子类无法使用父类的私有属性和方法
	}
}
package cn.sxt.oo2;

/**
 * 仍然测试封装
 *
 */
public class Person4 {
		private  int id;
		private String  name;
		private  int  age;
		private  boolean  man;  
		
		public   void  setName(String  name){
			 this.name = name;
		}
		
		public  String  getName(){
			return  this.name;
		}
		
		public  void setAge(int age) {
			if(age>=1&&age<=130){
				this.age = age;
			}else{
				System.out.println("请输入正常的年龄!");
			}
		}
		
		public  int  getAge(){
			return this.age;
		}

		public int getId() {
			return id;
		}

		public void setId(int id) {
			this.id = id;
		}

		public boolean isMan() {
			return man;
		}

		public void setMan(boolean man) {
			this.man = man;
		}
		
		
		
		
}

继承

• 类是对对象的抽象, 继承是对某一批类的抽象, 从而实现对现实世界更好的建模。
• 提高代码的复用性!
• extands的意思是“扩展” 。 子类是父类的扩展
• 不同的叫法: 超类、 父类、 基类、 子类、 派生类

在这里插入图片描述
在这里插入图片描述

  1. 通过继承可以简化类的定义, 实现代码的重用
  2. 子类继承父类的成员变量和成员方法, 但不继承父类的构造方法
  3. java中只有单继承 , 没有像c++那样的多继承。 多继承会引起混乱, 使得继承链过于复杂, 系统难于维护。 就像我们现实中, 如果你有多个父母亲, 那是一个多么混乱的世界啊。 多继承, 就是为了实现代码的复用性, 却引入了复杂性, 使得系统类之间的关系混乱。
  4. java中的多继承, 可以通过接口来实现
  5. 如果定义一个类时, 没有调用extends, 则它的父类是:java.lang.Object
package cn.sxt.oo2;

/**
 * 测试继承
 *
 */
public class TestExtends {
	public static void main(String[] args) {
		Student   stu  =  new Student();
		stu.name="高";
		stu.height = 172;
		stu.rest();
		
		Student  stu2 = new Student("希希",6,"挖掘机专业");
		
		System.out.println(stu2   instanceof  Student);
		System.out.println(stu2   instanceof   Person ); 
		System.out.println(stu2   instanceof   Object ); 
		System.out.println(new Person()   instanceof   Student ); 
		
	}
}


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(){
	}
	
	
}

方法的重写(override)

• 在子类中可以根据需要对从基类中继承来的方法进行重写。
• 重写方法必须和被重写方法具有相同方法名称、 参数列表和返回类型。
重写方法不能使用比被重写方法更严格的访问权限。 (由于多态)
在这里插入图片描述

Object类

• Object类是所有Java类的根基类
• 如果在类的声明中未使用extends关键字指明其基类, 则默认基类为Object类
在这里插入图片描述
• 重写: toString方法:
• 默认返回: 包名+类名+@+哈希码
• 可以重写!
• 打开API文档, 开始熟悉!
public class Person {

}
public class Person extends Object {

}
根据对象内存位置生成, 唯一不重复

package cn.sxt.oo2;

/**
 * 测试重写(override)/覆盖
 *
 */
public class TestOverride {
		public static void main(String[] args) {
			Horse   h   =  new Horse();
			h.run();
		}
}


class  Vehicle {
	public  void  run(){
		System.out.println("跑....");
	}
	
	public   void stop(){
		System.out.println("停止!");
	}
	
	public  Person   whoIsPsg(){
		return  new Person();
	}
	
}

class    Horse   extends  Vehicle {
	public  void  run(){
		System.out.println("四蹄翻飞,嘚嘚的。。。");
	}
	
	public  Student   whoIsPsg(){//返回值类型小于等于父类的类型
		return  new Student();
	}
	
}



super关键字

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

package cn.sxt.oo2;

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); //调用父类对象的成员变量
    }
}
package cn.sxt.oo2;
public class TestSuper02 { 
    public static void main(String[] args) {
        System.out.println("开始创建一个ChildClass对象......");
        new ChildClass2();
    }
}
class FatherClass2 {
    public FatherClass2() {
    	super();
        System.out.println("创建FatherClass");
    }
}
class ChildClass2 extends FatherClass2 {
    public ChildClass2() {
    	super();
        System.out.println("创建ChildClass");
    }
}

继承深化

  1. 父类方法的重写:
    • “==”: 方法名、 形参列表相同。
    • “≤≤” : 返回值类型和异常类型, 子类小于等于父类。
    • “≥” : 访问权限, 子类大于等于父类

  2. 构造方法调用顺序:
    • 根据super的说明, 构造方法第一句 总是: super(…)来调用父类对应的构造方法。
    • 先向上追溯到Object, 然后再依次向下执行类的初始化块和构造方法, 直到当前子类为止。

对象的比较— 和equals()
3.
• 比较两基本类型变量的值是否相等
• 比较两个引用类型的值即内存地址是否相等, 即是否指向同一对象。
4. equals() :
• 两对象的内容是否一致
5. 示例
• object1.equals(object2) 如: p1.equals(p2)
• 比较所指
对象的内容是否一样
,是比较两个对象, 而非两个基本数据类型的变量
• object1 == object2 如: p1==p2
• 比较p1和p2的值即 内存地址是否相等, 即是否是指向同一对象。
6. 自定义类须重写equals(), 否则其对象比较结果总是false。

package cn.sxt.oo2;

public class TestEquals {
	public static void main(String[] args) {
		Object obj;
		String str;
		
		User   u1 = new User(1000,"高淇","123456");
		User   u2 = new User(1000,"高希希","123456");
		
		System.out.println(u1==u2);
		System.out.println(u1.equals(u2)); 
		
		String  str1 = new String("sxt");
		String  str2 = new String("sxt");
		System.out.println(str1==str2);  //false
		System.out.println(str1.equals(str2));  //true
		
	}
}

class  User  {
	int id;
	String name;
	String pwd;
	
	public User(int id, String name, String pwd) {
		super();
		this.id = id;
		this.name = name;
		this.pwd = pwd;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (id != other.id)
			return false;
		return true;
	}
	
	
	
}

多态 polymorphism

• 多态性是OOP中的一个重要特性, 主要是用来实现动态联编的, 换句话说, 就是程序的最终状态只有在执行过程中才被决定而非在编译期间就决定了。 这对于大型系统来说能提高系统的灵活性和扩展性。
• java中如何实现多态?使用多态的好处?
• 引用变量的两种类型:
• 编译时类型(模糊一点, 一般是一个父类)
• 由声明时的类型决定。
• 运行时类型(运行时, 具体是哪个子类就是哪个子类)
• 由实际对应的对象类型决定。
多态的存在要有3个必要条件
要有继承, 要有方法重写, 父类引用指向子类对象
在这里插入图片描述

引用数据类型的类型转换
• 子类转换为父类: 自动转换
• 上转型对象不能操作子类新增的成员变量和方法。
• 上转型对象可以操作子类继承或重写的成员变量和方法
• 如果子类重写了父类的某个方法, 上转型对象调用该方法时, 是调用的重写方法。
• 父类转换为子类: 强制转换
• (绝不是做手术, 而是父类的真面目就是一个子类, 否则会出现类型转换错误)

final关键字

• final可以用来修饰变量, 方法, 类。

  1. 修饰变量: 变量一旦被初始化便不可改变, 相当定义了一常量。
    • final int x=3;
    • x=4;
  2. 修饰方法: final方法是在子类中不能被覆盖的方法
    • final returnType methodName(paramList){…}
    • final void eat() { … }
  3. 修饰类: final类是无法被任何类继承的。
    • final class finalClassName{ … }
    • final class Person{ … }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值