面向对象

本文深入讲解Java中的关键概念,包括对象与引用、this关键字、方法传递机制、构造函数顺序、多态、抽象类与接口的区别等,帮助读者理解Java编程的基础。

一、对象、引用

二、this

     表示当前对象,this默认引用的两个位置

1、构造器中引用,初始化对象

2、方法中引用,调用该方法的对象


三、Java里面的方法传递机制

        全部都是值传递:对于基础类型,传递其值;对于引用类型,传递一个引用(地址)


四、方法重载

  函数名相同,参数列表不同


五、成员变量和局部变量



六、访问控制符的修饰范围



七、继承

1、不支持多重继承

2、子类只能继承父类的非私有成员变量和方法

3、覆盖:覆盖一个方法并对其重写,以达到不同的作用

      当子类的成员变量和父类的相同时,子类会覆盖父类的成员变量,而不会继承;同理,函数相同(名字相同,相同参数与类型)时,也会覆盖


组合和继承的区别

组合:has-a

继承:is-a

例:

现有交通工具类Vehicle、汽车对象Car、轮胎对象Tire,那么三者之间的关系为Vehicle何Car之间是is-a,Car和轮胎之间是has-a

class Vehicle{
}
class Car extends Vehicle{}
class Tire{}
class Car extends Vehicle{
      private Tire t=new Tire();
}


八、构造函数的构造顺序:从Object->父类->子类(super关键字)

public class Base{
	public double size;
	public String name;
	public Base(double size,String name){
		this.size=size;
		this.name=name;
	}
	.....
}
public class Sub extends Base{
	public String color;
	public Sub(double size,String name,String color){
		super(size,name);
		this.color=color;
	}
	.....
}


九、多态

    1、概念

编译、运行的类型不一致就会出现多态

    2、多态发生的三个条件

        继承、重写、子类对象赋给父类引用(向上转型)

public class Baseclass {
	public int book=6;
	public void base(){
		System.out.println("父类的普通方法!");
	}
	public void test(){
		System.out.println("父类的被覆盖的方法!");
	}
}

public class Subclass extends Baseclass{

	//重新定义一个book实例属性覆盖父类的book
	public String book="父类book";
	public void test(){
		System.out.println("子类覆盖父类的方法");
	}
	public void sub(){
		System.out.println("子类的普通方法");
	}
	
	public static void main(String[] args) {
		//下面编译时类型和运行时类型不一样,多态发生
		Baseclass base=new Subclass();
		//输出6
		System.out.println(base.book);
               //调用执行从父类继承到的base方法
		base.base();
		//调用执行当前类的test方法
		base.test();
		//因为base的编译类型是baseclass,并没有提供sub()方法,因此会出现编译错误
		//base.sub();
	}
}


java中提供了哪两种用于多态的机制?

编译时多态和运行时多态。 编译时多态是通过方法的重载实现的,在编译时就确定调用哪个方法;运行时多态是通过方法的覆盖(子类覆盖父类方法)实现的,只有运行时才能确定到底调用哪个方法。

重载和覆盖有什么区别?

重载:

重载是指在一个类中定义了多个同名的方法通过不同的方法参数来区分的,不同的参数个数不同的参数类型不同的参数顺序

覆盖:

         覆盖是指派生类函数覆盖基类函数。覆盖一个方法并对其重写,以达到不同的作用。基类中被覆盖的方法不能为private,否则其子类只是定义了一个方法,并没有对其覆盖


十、强制转换

/*类型转换的原则
 * 1.基本类型之间的转换只能在数值类型之间进行,但数值型不能和布尔型之间进行转换
 * 2.引用类型之间的转换只能把一个父类变量转换为子类类型;如果试图把一个父类实例转换为子类类型,
 *   则必须这个对象实际上是子类实例才行(即编译时类型是父类类型,运行时类型是子类类型)
*/
public class TestCast {

	public static void main(String[] args) {
		double d=13.4;
		long l=(long)d;
		System.out.println(l);
		int in=5;
		//试图将一个数值类型转换为布尔类型,编译出错
		//boolean b=(boolean)in;
	
		Object obj="Hello";//向上转型
		//obj的编译类型是Object,是String的父类,可以强制转换;实际类型是String类型,运行时也可以通过
		String objString=(String)obj;//向下转型
		System.out.println(objString);
		
		Object obj1=new Integer(5);
		//编译时obj1是Object类型,可以转化为子类;运行时obj1是Integer,出错
		//String str=(String)obj1;
		
		//用instanceof来修改:instanceof用来判断是否可以进行强制转化;
		//前面的操作数要么跟后面的类相同,要么是后面类的父类
		if(obj1 instanceof String){
			String str=(String)obj1;
		}
	}
}


十一、初始化块

public class Root {
	static{
		System.out.println("Root的静态初始化块");
	}
	{
		System.out.println("Root的普通初始化块");
	}
	public Root(){
		System.out.println("Root的无参构造器");
	}
}

public class Mid extends Root{
	static{
		System.out.println("Mid的静态初始化块");
	}
	{
		System.out.println("Mid的普通初始化块");
	}
	public Mid(){
		System.out.println("Mid的无参构造器");
	}
	public Mid(String msg){
		this();//调用无参
		System.out.println("Mid的带参构造器,参数值为:"+msg);
	}
}

public class Leaf extends Mid{
	static{
		System.out.println("Leaf的静态初始化块");
	}
	{
		System.out.println("Leaf的普通初始化块");
	}
	public Leaf(){
		super("疯狂java");
		System.out.println("执行Leaf的构造器");
	}
}



java初始化的顺序:

父类静态变量-->父类静态代码块-->子类静态变量-->子类静态代码块-->父类非静态变量-->父类非静态代码块-->父类构造函数-->

子类非静态变量-->子类非静态代码块-->子类构造函数



十二、基础类型的包装类


1、自动拆、装箱

//装箱
Integer inObj=5;
//拆箱
int it=inObj;

2、包装类实现了基本类型变量和字符串之间的转换



十三、final

1、final变量

变量获得初始值就不可以更改(对于基本类型值不变,对于引用类型地址不变)

2、final方法

不可被重写

3、final类

不可以有子类


十四、不可变类

不可变类是指创建该类的实例之后,该实例的属性不可改变。

下面创建一个不可变类:

public class Address {
	//private、final修辞
	private final String detail;
	private final String postCode;
	//构造器里面初始化两个属性
	public Address(){
		this.detail="";
		this.postCode="";
	}
	public Address(String detail,String postCode){
		this.detail=detail;
		this.postCode=postCode;
	}
	//只生成get方法
	public String getDetail() {
		return detail;
	}
	public String getPostCode() {
		return postCode;
	}
	//重写equals
	public boolean equals(Object obj)
	{
		if(obj instanceof Address){
			Address ad=(Address)obj;
			if(this.getDetail().equals(ad.getDetail())&&this.getPostCode().equals(ad.getPostCode())){
				return true;
			}
		}
		return false;
	}
	//重写hashCode
	public int hashCode(){
		return detail.hashCode()+postCode.hashCode();
	}
}


十五、抽象类

包含抽象方法的类就是抽象类

抽象类里面的特征:抽象类可以包含属性、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类、枚举类这六种,抽象类的构造器不能用于创建实例,主要用于被子类调用

抽象类的作用:从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性

public abstract class Shape{
	{
		System.out.println("执行Shape的初始化...");
	}
	private String color;
	//求周长
	public abstract double claPerimeter();
	//返回形状
	public abstract String getType();
	//Shape构造器,并非用于创建对象,而是用于被子类调用
	public Shape(){}
	public Shape(String color){
		System.out.println("执行Shape的构造器...");
		this.color=color;
	}
	public void setColor(String color){
		this.color=color;
	}
	public String getColor(){
		return this.color;
	}
}

public class Circle extends Shape{
	private double radius;
	public Circle(String color,double radius){
		super(color);
		this.radius=radius;
	}
	public void setRadius(double radius){
		this.radius=radius;
	}
	//重写周长
	public double claPerimeter(){
		return 2*Math.PI*radius;
	}
	//重写返回形状的方法
	public String getType(){
		return getColor+"圆形";
	}
	
	public static void main(String[] args){
		Shape s=new Circle("红色",3.5);
		System.out.println(s.getType);
		System.out.println(s.claPerimeter);
	}
}

十六、接口(更彻底的抽象)

接口里面的特征:属性(常量)、方法(抽象方法)、内部类、枚举类;相对于抽象类说少了一般属性和一般方法

接口的作用:接口定义的是多个类共同的公共行为规范

        

接口的实现implements:实现接口与继承父类相似,获得所实现接口里定义的所有东西

//定义了一个接口规范:只要某个类能取得数据,并可以将数据输出,那他就是一个设备
public interface Output{//接口里定义的属性只能是常量
	int MAX_CACHE_LINE=50;
	//接口里定义的只能是public的抽象实例方法
	void getData(String msg);
	void out();
}
public interface Product{//定义一个Product接口
	int getProduceTime();
}

//让Printer类实现Output和Product接口
public class Printer implements Output,Product{
	private String[] printData=new String[MAX_CACHE_LINE];
	//用以记录当前需要打印的作业数
	private int dataNum=0;
	public void out(){
		//只要还有作业,继续打印
		while(dataNum>0){
			......
		}
	}
	public void getData(String msg){
		if(dataNum>=MAX_CACHE_LINE)
			System.out.println("输出队列已满,添加失败");
		else
			//把打印数据添加到队列中
			...
	}
	public int getProduceTime(){
		return 45;
	}
	
	public static void main(String[] args){
		//创建一个Printer对象,作为Output来使用
		Output o=new Printer();
		//还可以创建一个Printer对象,作为Product来使用
		Product p=new Printer();
	}
}

十七、抽象类与接口的区别

相同点:

(1)都不能实例化

(2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能被实例化、

不同点:

(1)接口只有定义,方法不能在接口中实现;抽象类可以有定义与实现

(2)一个类可以实现多个接口,因此接口可以用来间接地达到多重继承的目的

(3)接口强调的是"has-a",抽象类强调的是"is-a"

(4)接口中的成员变量默认为public static final,方法默认为public abstract;抽象类的成员变量默认为default,当然也可以改,方法不能用private、static修饰

(5)接口多用于不同类之间,抽象类多用于同类事物之间

        (6)接口相当于总纲,不应该经常被改变;抽象类体现的是模板设计,可以在以后的开发过程中根据需求适当改变


十八、内部类

http://www.cnblogs.com/mengdd/archive/2013/02/08/2909307.html


十八、反射

* 反射
* 通过.class文件获取类中的所有的内容。
* 先获取Class对象
* 类名 User.class;
* 实例对象 new User().getClass();
* Class.forName("类的包名+类名");

* 构造器、属性、方法。获取到都是对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值