Java基础之面向对象的基本概念(3)

                                                                Java基础之面向对象的基本概念(3)

</pre><p></p><p>本章继续说关于面向对象这些事,看上去没啥,但是里面有很多要深入理解的东西,很多学java的程序员,在这条道上大部分死于面向对象这个坎上,因为这个思想非常抽象,并且要深入代码和关键字进行实际的运用才能理解其中的奥秘。话不多说,回归正题。</p><p> </p><p>  Java程序中,大部分的java文件都是在包中存储的,这个包级的文件同时在一个java项目文件中存储,在你的workspace中可以找到你创建的java项目文件,顺着文件夹往下找即可发现你创建的包同时也是一个文件夹,里面有java文件,也有虚拟机编译好的class文件。</p><p>查找文件的方法:可以直接找到你的工作空间,或者右键点击java文件选择properties进入即可看到你的java文件的路径。</p><p>   因此本章从java的包开始说起。</p><p>一.Java的包 关键字  package</p><p>对包的作用描述:包是java语言有效管理类的方式,将同一个应用的类打入一个包中,把不相关或者是完成不同功能的类放入不同的包中,使得管理类变的更容易。包对管理相关类非常有效。</p><p> package是作为源文件的第一条语句,指明该文件定义的类所在的包:</p><p>语法格式: package<包名></p><p>包的命名规范:</p><p>1.使用英文字母作为包的名称。</p><p>2.包名要求全部使用小写字母表示(多个单词也全部小写)。</p><p>3.如果包名包含多个层次,每个层次应该用“.”分割。</p><p>例如:</p><p>package helloworld;</p><p>Package cn.com.sun.java;</p><p>每个层次的点区分为一个文件夹,比如cn文件夹里有com;com文件夹下有sun;sun文件夹下有java,然后java文件夹里就是你的java文件了(也就是class);</p><p>但是这些包一般放在一名字是src里的文件夹下,该文件夹下的文件称为源文件。</p><p> </p><p>另外一个与包相关的关键字是import</p><p>因为在java语言中很多类已经为我们写好啦,我们可以用这个关键字引用java API里的类,方便我们进行程序编写。些类可能在不同的包中。如果需要引入其他包中的类,可以使用如下语法格式:</p><p>import <包名.类名>;</p><p>import关键字</p><p>1.如果要引入某个包中的所有类,可以使用如下语法格式:</p><p>import <包名>.*;      //※代表该包下的所有文件</p><p>2.在学习Java语言时,使用已经存在的类,避免一切从头做起,是</p><p>学习面向对象编程的一个重要方面。</p><p>可以使用ctrl+shift+o实现引入包的操作,是个快捷键。或者按ctrl将鼠标放到引入的java文件名上,如果有源码的话可以进入查看源码。</p><p></p><p> </p><p>二.继承 关键字   extends </p><p><span style="color:#ff0000">Java中的继承是面向对象的三大特征之一,也是实现软件复用的重要手段,继承是一种基于已有的类创建新类的机制。</span></p><p>java语言机制允许单继承,就是每个类只有一个父类,不允许有多个父类,这也是区别于C/C++的一个特点。</p><p>简要说明:实现继承的类称为子类,被继承的类称为父类,基类或者超类。比如水果和香蕉的关系,水果是父类,苹果是水果。子类是一种特殊的父类,父类的范围总比子类的范围大。</p><p> </p><p><span style="color:#cc0000">深度说明:利用继承,我们可以先创建一个具有共有属性的一般类,根据该一般类再派生出具有特殊属性的新类,新类继承一般类的状态(成员变量)和行为(方法),并根据需要增加额外的状态(成员变量)和行为(方法)。由继承而得到的类称为子类(或派生类),被继承的类称为父类(或超类)。Java中每个类只允许有一个父类。</span></p><p> </p><p>语法格式:  class <类名> extends <父类名></p><p>扩展说明:extends在英语中是扩展的意思,但继承这个词很好的体现了子类和父类之间的关系。</p><p>   子类继承父类后可以做哪些事呢,有什么特性呢,有什么好处呢,缺点又有什么呢?接下来依次解析。</p><p> </p><p>  1子类继承父类后可以获得父类的除private的变量和方法外,其他的都可以获得,就像基因一样,有些可以从父亲那里得到,有些父亲有的子类不一定有,因为父类的private方法,和变量是私有的,不能被子类得到。</p><p>  2.子类得到父类的变量,方法,可以对这些变量方法做什么</p><p>   1.子类可以调用父类的变量,方法进行操作。</p><p>2.子类可以定义与父类相同的方法。</p><p>3.子类可以定义与父类相同的变量。</p><p>其中2的操作称为覆盖(Override),也叫重写。</p><p>重写的概念:</p><p><span style="color:#ff0000">当子类方法的名字,返回类型,及参数个数和参数类型与父类的方法完全相同时,父类的同名方法将被隐藏。而这种子类方法覆盖父类方法的现象叫做重写。</span></p><p>重写的注意事项:遵循“两同两小一大”的原则。</p><p>  说明:</p><p>    1.”两同”方法名相同,形参列表相同。</p><p>    2.“两小”:子类方法返回值应该比父类方法的返回值类型更小或相同,子类方法声明抛出的异常应该比父类方法声明抛出的异常类更小或者相同。</p><p>    3.“一大”:子类方法的访问权限应该比父类方法的访问权限更大,或者相同,否则报错。</p><p>    4.子类与父类的方法类型应该相同,要么都是实例方法,要么都是类方法。</p><p>    5.即使子类的某些方法与父类的private方法一样,依然不是重写,可以加static成为类方法,也可以不加。</p><p>    6.子类重写父类的方法后子类的对象将无法访问父类中被重写的方法,但是可以在子类方法中调用父类被中被重写的方法。可以使用super(被重写的实例方法)或者父类类名(被重写的是类方法)作为调用者来调用父类中被重写的方法。</p><p> </p><p>其中3的操作说明:当子类的成员变量和父类中的成员变量同名时,父类的成员变量不能被子类继承(即被子类的成员变量覆盖),此时称子类的成员变量隐藏了父类的成员变量。有时候也称覆盖,但是覆盖与隐藏不是一回事。</p><p>子类对象的调用规则</p><p>对于子类实例化的一个对象,如果在子类中重写了父类的方法,则运行时系统调用子类重写的方法;如果子类继承了父类的方法(未重写),那么子类实例化的对象会调用继承自父类的方法。</p><p> </p><p>继承的优点:</p><p> 成员变量的隐藏和方法重写可以使子类替换父类中并不适合子类的状态(变量)和行为(方法),从而使继承更加灵活。可以很容易的修改和扩展已有的实现。</p><p> </p><p>继承的缺点:</p><p> 1.继承体系了耦合性,而我们目前的开发程序的思想是要尽量降低耦合性,提高可扩展性。</p><p>2.尽量少从具体类继承,继承接口,或抽象类比较好。</p><p>3.继承不利于维护。</p><p>4.继承破坏了类的封装性。</p><p>5.白盒重用,因为基类的内部细节通常对子类是可见的。</p><p>6.当父类的实现改变时,可能要相应的改变子类。</p><p>7.不能在运行时改变由父类继承来的实现。</p><p>在effectIvejava中更加会考虑组合方式。</p><p>只有当下列条件满足时才考虑使用继承</p><p>  1.子类是一种特殊的类型,而不只是父类的一个角色。</p><p>  2.子类的实例不需要变成另一个类的对象。</p><p>  3.子类扩展,而不是覆盖或者使父类的功能失效。</p><p> </p><p>Java中继承的特点:</p><p> 1.通过继承可以简化类的定义。</p><p> 2.java只支持单继承。</p><p> 3.java的继承可以有多个层次。</p><p> 4.子类不能继承父类的构造方法,子类可以使用语句super(参数列表),调用父类的构造方法。</p><p> 5.子类的构造方法没有显示的调用父类的构造方法,也没有用this关键字调用重载的其他构造方法,在子类产生子类的实例对象时,系统默认调用父类无参的构造方法。</p><p> 6.继承提供了软件复用的功能。</p><p> </p><p>三、访问权限</p><p>    说明:  当使用某个类创建了相应的对象之后,可以使用</p><p><对象名>.<变量名>和<对象名>.<方法名>这样的语法格式访问变量和方法。但这种访问是受权限限制的,使用private、protected和public设置相应的权限级别。</p><p> </p><p>   在java中共有4种访问级别,按访问权限由高到低为:public(公有的)、protected(受保护的)、友好的(没有任何访问权限关键字修饰)和private(私有的)。</p><table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top"><p>类型</p></td><td valign="top"><p>类的内部</p></td><td valign="top"><p>同一个包的其他类(包含子类)</p></td><td valign="top"><p>不同包的子类</p></td><td valign="top"><p>不同包的非子类</p></td></tr><tr><td valign="top"><p>public</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p>Yes</p></td></tr><tr><td valign="top"><p>protected</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p> </p></td></tr><tr><td valign="top"><p>Friendly(友好的)</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td></tr><tr><td valign="top"><p>private</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td></tr></tbody></table><p> </p><p>其中变量的访问级别与方法的访问级别相同,在此不做图表了。</p><p>同样有子类访问父类的规则,这两个表定义了java的代码访问权限,保证了封装性和多态性</p><table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top"><p>类型</p></td><td valign="top"><p>父类和子类在同一个包中</p></td><td valign="top"><p>父类和子类不在同一个包中</p></td></tr><tr><td valign="top"><p>public</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p>Yes</p></td></tr><tr><td valign="top"><p>protected</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p>Yes</p></td></tr><tr><td valign="top"><p>Friendly(友好的)</p></td><td valign="top"><p>Yes</p></td><td valign="top"><p> </p></td></tr><tr><td valign="top"><p>private</p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td></tr></tbody></table><p> </p><p>下面给出一个关于上述知识点的代码:</p><p></p><pre name="code" class="java">public class Father {
	public String name ="张三" ;        //父亲的姓名,子类应该知道
	protected int age = 34 ;           //父类的年龄,子类应该也知道
	String    food ="红烧肉";            //父类喜欢的食物,子类也会知道
	private   double  money = 1000.0 ;  //父类的私房钱,子类是不能知道的,因为是私房钱嘛。
	public static String workName = "java高级攻城尸";  //类变量
	
	/**
	 * public Father(){}  //父类的无参构造方法,如果显示的提供,则子类必须实现构造方法。
	 * @param _name
	 */
	public Father(String _name){
		this.name = _name;
	}
	/**
	 * 访问级别:共有方法,可以被被任何其他类访问。
	 * 
	 * 时间:2014年8月15日
	 * 返回:void
	 */
	public void saySon(){
		System.out.println("我是父类:  "+this.name);
	}
	/**
	 * 友好的方法只能被相同的包下的其他类访问。
	 * 
	 * 时间:2014年8月15日
	 * 返回:void
	 */
	void info(){
		System.out.println("我的经历非常丰富。。。");
	}
	/**
	 * 受保护的方法可以被相同包下的其他类访问,还有该类的子类访问。
	 * 
	 * 时间:2014年8月15日
	 * 返回:void
	 */
	protected void like(){
		System.out.println("我的偶像是刘德华。。。。");
	}
	/**
	 * 私有方法,只能在当前类的内部访问。
	 * 
	 * 时间:2014年8月15日
	 * 返回:void
	 */
	private void fathermoney(){
		System.out.println("我藏了点私房钱,嘿嘿。。。。。");
	}
	public void work(String name){
		System.out.println("我是一位程序员。。。。。"+name);
	}
}

package cn.com.basicOne;
/**
 * 
 * @author fcs
 * 2014年8月15日
 * Son
 * 说明:注意main方法和main2()方法的区别。
 */
public class Son extends Father{
		
		/**
		 * @param _name
		 * 说明:父类如果提供了无参的构造方法,子类的这个构造方法可以不用写,当父类没有无参构造方法的时候,
		 * 子类必须实现下面的构造方法
		 */
		public Son(String _name) {
			super(_name);     //默认先调用父类的构造方法。 
		}
		
		public String name;   //子类也有名字,会覆盖父类的name
		protected int age;    //子类也有年龄,会覆盖父类的age
		
		/**
		 * 子类重写父类的方法work
		 */
		public void work(String name){
			System.out.println("我是一名学生:"+name);
			super.work(name+"的父亲");   //使用super关键字调用父类的被重载的方法
		}
		/**
		 * 
		 * 作者:FCs
		 * 描述:子类在方法中调用父类的变量,包括被覆盖的变量。
		 * 时间:2014年8月15日
		 * 返回:void
		 */
		public void getField(){
			System.out.println("子类在方法中调用父类的变量,包括被覆盖的变量");
			System.out.println(super.food);
			System.out.println(super.name);
			System.out.println(super.age);
		}
		
		public void setField(){
		    super.food = "青椒炒肉。。。。。";
			super.name = "李四";   //可以允许这样,但是运行时会报错。
		System.out.println("更改后再次访问:----:  "+super.food);
		System.out.println("更改后再次访问:----:  "+super.name);
		}
		//测试方法,不能通过super关键字在static方法中得到父类的实例变量
		public static void main(String[] args) {
			Son son  = new Son("张三");
			System.out.println("------------子类调用(获取)父类的方法--------------");
			son.saySon();  //子类调用父类的public方法
			son.info();    //子类调用父类的友好方法(friendly)无修饰符的
			son.like();    //子类调用父类的protected被保护的方法
			System.out.println("子类得不到父类的私房钱的方法。。。。");
			System.out.println("-------------子类获取父类的变量--------------");
			System.out.println(son.age);           //当子类出现age变量时会调用子类的变量默认为 0
			System.out.println(son.food); 		   //当子类没有出现父类的变量food,调用父类的food变量
			System.out.println(son.name);          //当子类出现age变量时会调用子类的变量默认为 null
			System.out.println("子类得不到父类的私房钱的变量。。。。。\n");
			
			System.out.println(son.workName);     //获取父类的类变量
			son.getField();
			son.work("张三");
			System.out.println("---------------------------------");
			son.setField();
			
			
		}
		public void main2(){
			Father son  = new Son("张三"); //这种方式叫上转型对象
			System.out.println("------------子类调用(获取)父类的方法--------------");
			son.saySon();  //子类调用父类的public方法
			son.info();    //子类调用父类的友好方法(friendly)无修饰符的
			son.like();    //子类调用父类的protected被保护的方法
			System.out.println("子类得不到父类的私房钱的方法。。。。");
			System.out.println("-------------子类获取父类的变量--------------");
			System.out.println(son.age);           //当子类出现age变量时会调用子类的变量默认为 0
			System.out.println(son.food); 		   //当子类没有出现父类的变量food,调用父类的food变量
			System.out.println(son.name);          //当子类出现age变量时会调用子类的变量默认为 null
			System.out.println("子类得不到父类的私房钱的变量。。。。。\n");
			
			System.out.println(son.workName);     //获取父类的类变量
			((Son) son).getField();  //这是调用子类的方法应该进行下转型
			son.work("张三");
			System.out.println("---------------------------------");
			((Son) son).setField();  //这是调用子类的方法应该进行下转型
		}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值