Java面向对象三大特征

1:封装

含义:它指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。

封装的好处:

(1):隐藏类的实现细节。

(2):让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制对成员变量的不合理访问。

  (3):可进行数据检查,从而有利于保证对象信息的完整性。

  (4):便于修改,提高代码的可维护性。

封装的原则:

  (1):将不需要对外提供的内容隐藏起来。

  (2):把实现细节隐藏,提供可以对其进行访问的公共的方式。

封装的方式:使用访问控制符。

Java提供了3个访问控制符:private,protected和public,分别代表了三个访问控制级别,另外还有一个不加任何访问控制符的访问控制级别,提供了4个访问控制级别。Java的访问控制级别有小到大的关系如下:

                                                    private->default->protected->public

 private:如果类里的一个成员(包括成员变量,方法和构造器等)使用 private访问控制符修饰,则这个成员只能在当前类的内  部被访问。

default:如果类里的一个成员(包括成员变量,方法和构造器等)或者一个外部类不使用任何访问控制符修饰,则这个成员或外部类可以被相同包下其他类访问。

protected:如果类里的一个成员(包括成员变量,方法和构造器等)使用protected访问控制符修饰,那么这个成员既能被同一个包内的其他类访问,也可以被不同包中的子类访问。

public:如果类里的一个成员(包括成员变量,方法和构造器等)或者一个外部类使用public访问控制符修饰,则这个成员或外部类可以被所有类访问。

                                                                                  访问控制级别表

  private default protected public
同一个类中
同一个包中  
子类中    
全局范围内      
下面定义了一个Person类,这个Person类实现了良好的封装
public class Person 
{
	  //使用private修饰成员变量,将这些成员变量隐藏起来
	private String name;
	private int age;
	//提供方法来操作name成员变量
	public void setName(String name)
	{
		//执行合理性效验,要求用户名必须在2~6为之间
		if(name.length() > 6 || name.length() < 2)
		{
			System.out.println("您设置的人名不符合要求");
			return;
		}
		else
		{
			this.name = name;
		}
	}
	public String getname()
	{
		return this.name;
	}
	//提供方法来操作age成员变量
	public void setAge(int age)
	{
		//执行合理性效验,要求用户年龄必须在0~100为之间
		if(age > 100|| age < 0)
		{
			System.out.println("您设置的年龄不合法");
			return;
		}
		else
		{
			this.age = age;
		}
	}
	public int getAge()
	{
		return this.age;
	}
}

【因为Person类的name和age两个成员变量是private修饰的,所以在Person类之外只能通过各自的setter和getter方法来操作和访问他们】

2:继承

Java的继承通过extends关键字来实现,实现继承的类被称为子类,被继承的类成为父类,有的也称为基类,超类。

Java里子类继承父类的语法格式如下:

修饰符 class SubClass extends SuperClass
{
      //类定义部分
}

下面的代码示范了子类继承父类的特点。

public class Fruit 
{
	   public double weight;
	   public void info()
	    {
	        System.out.println("我是一个水果!重"+weight+"g!");
	    }
}


public class Apple extends Fruit
{
	public static void main(String[] args)
	{
		//创建Apple对象
		Apple a = new Apple();
		//Apple对象本身没有weight成员变量
		//因为Apple的父类有weight成员变量,也可与访问Apple对象的weight成员变量
		a.weight = 56;
		//调用Apple对象的info()方法
		a.info();
	}
}

注意:【每个类最多只有一个直接父类,但可以拥有无限个间接父类】

例如:

class Fruit extends Plant{...}
class Apple extends Fruit{...}

一个关键字:super

如果需要在子类方法中调用父类被覆盖的实例方法或变量,则可以使用super限定来调用父类被覆盖的实例方法或变量。

如果在构造器中使用super,则super用于限定该构造器初始化的是该对象从父类继承得到的实例变量,而不是该类自己定义的实例变量。

注意:【super不能出现在static修饰的方法中。】

下面的代码很好的体现了super的用法:

public class BaseClass {
	public int a = 5;
}
public class SubClass extends BaseClass
{
	public int a = 7;
	public void accessOwner()
	{
		System.out.println(a);
	}
	public void accessBase()
	{
		System.out.println(super.a);
	}
	public static void main(String[] args)
	{
		SubClass sc = new SubClass();
		sc.accessOwner();//输出7
		sc.accessBase();//输出5
	}
}

3:多态

Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态。

下面的代码示范了多态的特征:

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 =  "这是一本书";
	public void test()
	{
		System.out.println("子类的覆盖父类的方法");
	}
	public void sub()
	{
		System.out.println("子类的普通方法");
	}
	public static void main(String[] args)
	{
		//下面编译时类型和运行时类型完全一样,因此不存在多态
		BaseClass bc = new BaseClass();
		//输出6
		System.out.println(bc.book);
		bc.base();
		bc.test();
		//下面编译时类型和运行时类型完全一样,因此不存在多态
		SubClass sc = new SubClass();
		//输出“这是一本书”
		System.out.println(sc.book);
		sc.base();
		sc.test();
		//下面编译时类型和运行时类型不一样,因此发生多态
		BaseClass pl = new SubClass();
		//输出6--表面访问的是父类对象的实例变量
		System.out.println(pl.book);
		pl.base();
		//下面调用将执行当前类的test()方法
		pl.test();
	}
}

从上面代码可以看出,第三个引用变量pl比较特殊,他的编译时类型是BaseClass,而运行时类型是SubClass,当调用改引用变量的test()方法I(BaseClass类中定义了该方法,但SubClass覆盖了父类的该方法)时,实际执行的是SubClass类中覆盖后的test()方法,这就可能出现多态了。

注意:【与方法不同的是,对象的实例变量则不具备多态性。比如上面的pl引用变量,程序中输出它的book实例变量时,并不是输出SubClass类里定义的实例变量,而是输出BaseClass类里的实例变量。】

总结:【相同类型的变量,调用同一个方法是呈现出多种不同的行为特征,这就是多态。】

猜你喜欢

转载自blog.csdn.net/qq_41430599/article/details/79719580