Java 第九课:Java对象

套用linux“一切皆文件”的思想,Java语言可以说一切皆对象。因此,学习 Java 语言必须掌握对象(实质上类可以看作是对象的抽象,它定义了对象的具体属性和方法),这样可以从深层次理解 Java 这种面向对象语言的幵发理念。

一、对象的概念
所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念。

对象有以下特点:
对象具有属性和行为。
对象具有变化的状态。
对象具有唯一性。
对象都是某个类别的实例。
一切皆为对象,真实世界中的所有事物都可以视为对象。

向对象程序设计有以下优点:
1. 可重用性:它是面向对象软件开发的核心思路,提高了开发效率。面向对象程序设计的抽象、继承、封装和多态四大特点都围绕这个核心。
2. 可扩展性:它使面向对象设计脱离了基于模块的设计,便于软件的修改。
3. 可管理性:能够将功能与数据结合,方便管理。

二、Java继承
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

继承的语法格式:
class 父类名 {

}
class 子类名 extents 父类名 {

}
继承的优势:提高代码的复用性,易于维护。

2.1. 继承的特性:
	1. 子类具有父类非private的属性和方法
	2. 子类可以扩展父类没有的方法
	3. 子类可以用自己的方法实现父类的方法
	4. Java的继承是单继承和多重继承,不支持多继承

2.2 关键字
	1. 继承的关键字:extends和implements来实现继承。而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。

	2 super 与 this 关键字:
	super:通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
	this:指向自己的引用。

	3. final关键字:
	final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:
	声明类语法格式:
	final class 类名 {
		//类体
	}

2.3 Java构造器
	构造器的注意事项:
	1.构造器的名称必须和类名一致;
	2.一个类中可以定义多个构造器,但是构造器的参数列表必须不同;
	3.如果我们没有手动定义构造器,则java系统会提供一个默认的构造器给我们使用。一旦我们定了构造器,则系统会把构造器收回;
	4.构造器的作用:实例化对象,给对象赋初始值;
	5.代码游离块优先执行。

2.4 instanceof 关键字
	可以使用 instanceof 运算符来检验一个子类是否是一个父类的一个实例。 
参考实例:
public class MyClassTest {
	public static void main(String[] args) {
		System.out.println("Show class info:");
	
		Dog dog = new Dog("qiuqiu", 1);
		dog.eat();
		dog.sleep();
		dog.showInfo();
		dog.look();
		
		Mouse mouse = new Mouse("xixi", 2);
		mouse.eat();
		mouse.sleep();
		mouse.showInfo();
		mouse.action();
				
		System.out.println(dog instanceof Animal);
		System.out.println(mouse instanceof Animal);
	}
}

/*
 * 父类
 */
class Animal {
	private String priName;
	private int priId;
	
	//构造器
	public Animal(String name, int id) {
		priName = name;
		priId = id;
	}
	
	public void eat() {
		System.out.println(priName + " eating!");
	}
	public void sleep() {
		System.out.println(priName + " sleeping!");
	}
	public void showInfo() {
		System.out.println("name is " + priName + " id " + priId);
	}
}

/*
 * 子类
 */
class Dog extends Animal {
	public Dog (String name, int id) {
		super(name, id);
	}
	public void look() {
		System.out.println("看家");
	}
}

/*
 * 子类
 */
class Mouse extends Animal {
	public Mouse(String name, int id) {
		super(name, id);
	}
	public void action() {
		System.out.println("搞破坏");
	}
}

输出结果:
	Show class info:
qiuqiu eating!
qiuqiu sleeping!
name is qiuqiu id 1
看家
xixi eating!
xixi sleeping!
name is xixi id 2
搞破坏
true
true
注意:
Java不支持多继承,但支持多重继承。
class A {
}

class B {
}
//单继承
class C extends A{
}
//多重继承
class D extends C{
}
//单继承
class E extends A{
}
//class F多继承,非法
class F extends A, B{
}

三、Java多态
多态是同一种行为具有多种不同的表现形式。Java中,所有的对象都具有多态性。
比如我们说动物这个对象,他可以有多种表现形式,比如猫,狗等。当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的优点
	1. 消除类型之间的耦合关系
	2. 可替换性
	3. 可扩充性
	4. 接口性
	5. 灵活性
	6. 简化性	

多态存在的三个必要条件
    继承
	重写
	父类引用指向子类对象

多态的实现方式
	方式一:重写,重写(Override)与重载(Overload)。

	方式二:接口
		1. 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。
    	2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。
	方式三:抽象类和抽象方法 

四、抽象类
Java中所有对象都是用类来描述的,但不是所有的类都可以描述对象。如果一个类中,没有足够的信息来表示一个对象,这个类就是抽象类。由于抽象类不能实例化对象,所有抽象类必须被继承才能被使用。

抽象类规定:
	1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
	2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
	3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
	4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
	5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。		

Java中使用abstract class来定义抽象类。
实例:
文件:Lesson2.java
package lesson2;
public class Lesson2 {
	public static void main(String[] args) {
		System.out.println("Lesson2 Class.");
		//Students students = new Students("lili", "woman", 22);
		//students.showInfo();
		
		Yoyo stu1 = new Yoyo("yoyo", "girl", 22);
		System.out.println(stu1.getAge());
		stu1.setScore(99.8);
		System.out.println(stu1.getScore());
		System.out.println(stu1.getName());
		System.out.println(stu1.getSex());
		stu1.showInfo();
	}
}

文件:Students.java
package lesson2;

public abstract class Students
{
	private String name;
	private int age;
	private String sex;
	
	public Students(String name, String sex, int age) {
		System.out.println("构造器");
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public String getSex() {
		return sex;
	}
	
	public int getAge() {
		return age;
	}
	
	public void showInfo() {
		System.out.println("name is " + name + " age: " + age);
	}
}

文件:Yoyo.java
package lesson2;

public class Yoyo extends Students {
	private double score;
	
	public Yoyo(String name, String sex, int age) {
		super(name, sex, age);
	}
	
	public double getScore() {
		return score;
	}
	
	public void setScore(double score) {
		this.score = score;
	}
}
输出结果:
Lesson2 Class.
构造器
22
99.8
yoyo
girl
name is yoyo age: 22
抽象方法
**如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法**。
Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。
抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。
public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();		//抽象方法
   //其余代码
}
	注意:
	声明抽象方法会造成以下两个结果:
	    1. 如果一个类包含抽象方法,那么该类必须是抽象类。
    	2. 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
	继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

五、Java封装
封装是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

优点:
	1. 良好的封装能够减少耦合。
	2. 类内部的结构可以自由修改。
	3. 可以对成员变量进行更精确的控制。
	4. 隐藏信息,实现细节。
实例参考第四部分Java抽象类。

六、Java 重写(Override)重载(OverLoad)

1.重写
所谓重写就是子类对父类允许的方法的实现进行重新编写,但不能改变行参和返回值。
class Animal {
	public void move() {
		System.out.println("动物可以移动");
	}
}

class Dog extends Animal {

	//重写move
	public void move() {
		System.out.println("狗可以跑");
	}
	//子类独有方法
	public void bark() {
		System.out.println("狗会叫");
	}
}

class Fish extends Animal {
	
	//重写move
	public void move() {
		super.move();							//调用父类方法。super关键字
		System.out.println("鱼可以游");
	}
}

public class MyClassTest {
	public static void main(String[] args) {
		System.out.println("Lession2: 重写");
		Animal animal = new Animal();
		Animal dog = new Dog();
		Dog dog2 = new Dog();
		Animal fish = new Fish();
		animal.move();
		dog.move();
		//dog.bark();		//编译错误,因为父类没有bark()方法
		dog2.bark();
		dog2.move();
		fish.move();
	}
}

输出结果:
Lession2: 重写
动物可以移动
狗可以跑
狗会叫
狗可以跑
动物可以移动
鱼可以游
重写注意规则:
	1. 参数列表必须完全与被重写方法的相同;
	2. 返回类型必须完全与被重写方法的返回类型相同;
	3. 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
	4. 父类的成员方法只能被它的子类重写。
	5. 声明为final的方法不能被重写。
	6. 声明为static的方法不能被重写,但是能够被再次声明。
	7. 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
	8. 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
	9. 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
	10. 构造方法不能被重写。
	11. 如果不能继承一个方法,则不能重写这个方法。

Super关键字的使用
	当需要在子类中调用父类的被重写方法时,要使用super关键字。 

2. 重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。最常用的地方就是构造器的重载。
	实例:
	public void overload() {
		System.out.println("overLoad");
	}
	
	public void overload(String name) {
		System.out.println("overLoad " + name);
	}
	
	public void overload(int num) {
		System.out.println("overLoad " + num);
	}

	static void MyOverLoad() {
		MyClassTest ol = new MyClassTest();
		ol.overload();
		ol.overload(1);
		ol.overload("lili");
	}
	输出结果:
		overLoad
		overLoad 1
		overLoad lili
3. 重写和重载区别:
						 	重载	 				重写
	参数列表	    必须修改 			一定不能修改
	返回类型		可以修改 			一定不能修改
	异常				可以修改 			可以减少或删除,一定不能抛出新的或者更广的异常
	访问				可以修改 			一定不能做更严格的限制(可以降低限制)

七、Java接口
接口在Java中以Interface来声明,虽然接口的方法和类相似,但接口并不是类,他们属于不同的概念。接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。

7.1 接口特性
    1. 口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
	2. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
	3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

7.2 接口与类相似点:
	1. 一个接口可以有多个方法。
	2. 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
	3. 接口的字节码文件保存在 .class 结尾的文件中。
	4. 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

7.3 接口与类的区别:
	1. 接口不能用于实例化对象。
	2. 接口没有构造方法。
	3. 接口中所有的方法必须是抽象方法。
	4. 接口不能包含成员变量,除了 static 和 final 变量。
	5. 接口不是被类继承了,而是要被类实现。
	6. 接口支持多继承。

7.4 接口的语法格式:
	[可见度] interface 接口名称 [extends 其他的接口名名] {
    	// 声明变量
    	// 抽象方法
	}
	
7.5 接口的实现:
	当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。
	类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。
	语法格式:
		[可见度] class 对象名 implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...

7.6 重写接口中声明的方法时的规则:
    1. 类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
	2. 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
	3. 如果实现接口的类是抽象类,那么就没必要实现该接口的方法。

7.7 在实现接口的时候,也要注意一些规则:
   	1. 一个类可以同时实现多个接口。
	2. 一个接口能继承另一个接口,这和类之间的继承比较相似。
实例:
Lesson2.java
package lesson2;
public class Lesson2 {
	public static void main(String[] args) {
		System.out.println("Lesson2 Class.");
		//Students students = new Students("lili", "woman", 22);
		//students.showInfo();
		
		Yoyo stu1 = new Yoyo("yoyo", "girl", 22);
		System.out.println(stu1.getAge());
		stu1.setScore(99.8);
		System.out.println(stu1.getScore());
		System.out.println(stu1.getName());
		System.out.println(stu1.getSex());
		stu1.showInfo();
	}
}

Students.java
package lesson2;

public abstract class Students
{
	private String name;
	private int age;
	private String sex;
	
	public Students(String name, String sex, int age) {
		System.out.println("构造器");
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public String getSex() {
		return sex;
	}
	
	public int getAge() {
		return age;
	}
	
	public void showInfo() {
		System.out.println("name is " + name + " age: " + age);
	}
}
Yoyo.java
public class Yoyo extends Students implements StudentsScore {
	private double score;
	
	public Yoyo(String name, String sex, int age) {
		super(name, sex, age);
	}
	
	public double getScore() {
		System.out.println("get score.");
		return score;
	}
	
	public void setScore(double score) {
		System.out.println("set score");
		this.score = score;
	}

	@Override
	public void setScore() {
		// TODO Auto-generated method stub
		
	}
}
StudentsScore.java
package lesson2;

public interface StudentsScore {
	public double getScore();
	public void setScore();
}
输出结果:
	Lesson2 Class.
	构造器
	22
	set score
	get score.
	99.8
	yoyo
	girl
	name is yoyo age: 22
7.8 接口的继承
	一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。
	Java中,类的多继承是不合法,但接口允许多继承。
	在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。
	语法格式:
	public interface 接口名 extends 接口名2, 接口名3
// 文件名: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}
 
// 文件名: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}
7.9 标记接口
	最常用的继承接口是没有包含任何方法的接口。标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。
	
	标记接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。
	1. 建立一个公共的父接口:
	    正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。
	2. 向一个类添加数据类型:
		这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

例如:java.awt.event 包中的 MouseListener 接口继承的 java.util.EventListener 接口定义如下:
package java.util;
public interface EventListener
{}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值