黑马程序员—java基础—面向对象

这篇博客详细介绍了Java的面向对象编程基础,包括面向对象的三大特性——封装、继承和多态。首先,解释了面向对象的概念,强调了其简化复杂问题和符合人类思维方式的优势。接着,讨论了类和对象的定义,成员变量和局部变量的区别,以及构造方法的使用。文章还提到了封装的重要性,解释了私有化关键字`private`的作用。最后,简要介绍了继承的概念,`this`和`super`关键字的应用,以及多态的基本原理。

                                                                    ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

 

 

面向对象是java语言的基础,贯穿于java语言的全部过程。一谈到面向对象,脑海里闪现出一句话:万物皆对象。面向对象这里重要的知识点有三个,封装,继承,和多态。准备把面向对象这个模块分成五个大标题,即面向对象概念导入。封装,继承,和多态。面向对象运用。

 

一,面向对象导入

什么是面向对象:面向对象是基于面向过程的,面向过程是指实现一个功能,我们是功能的参与者,必须亲力亲为,关注每一个步骤和过程。而面向对象,则是强调对象的,面向对象就是创建一个实物类的实例,这个对象实现某个事物的功能,具体的实现过程不需要我们管,2:面向对象思想特点:
                                    A:符合我们思考的思想
                                    B:把复杂的事情简单化
                                    C:你从执行者变成了指挥者

 

类是一组属性和事物的集合,是一个抽象概念,对象则是这个抽象类事物的具体实例。一个类里面有很多的属性,属性在类里面用变量表示,事物的行为则用方法表示。成员变量:类中方法外的变量属于成员变量。

 

创建对象格式:

类名 对象名 = new 类名();

使用对象属性:

对象.属性名

使用对象方法

对象名.方法名();

 

成员变量和局部变量:

 

A:在类中的位置不同
  成员变量:在类中方法外
  局部变量:在方法定义中或者方法声明上,定义在语句中  for循环 定义在语句中,就在for循环语句中管用
 B:在内存中的位置不同
  成员变量:在堆内存
  局部变量:在栈内存
 C:生命周期不同  作用域不同
  成员变量:随着对象的创建而存在,随着对象的消失而消失
  局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
 D:初始化值不同
  成员变量:有默认初始化值
  局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。

 

能否成功创建对象,取决于构造方法:

A:构造方法概述和作用
创建对象,给对象中的成员进行初始化
B:构造方法格式特点
      a:方法名与类名相同
      b:没有返回值类型,连void都没有
      c:没有具体的返回值

构造方法注意事项:

      a:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
      b:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
      注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
     C:给成员变量赋值的两种方式

      1,构造方法传参

      2,setXxx方法。(一般是由于成员属性私有化)

面向对象基本:一个标准的学生类代码:

/**
 *  学生类:
 *     成员变量:姓名 年龄  应该是被private修饰
 *	  构造方法:
 *	         无参的  
 *			 带参的  两个参数
 *	  成员方法:
 *	        setXxx();  getXxx();
 *			eat();     show();
 */
class Student{
	 //定义成员变量
     private String name;
	 private int age;
     //定义构造方法
	 //无参构造方法
	 public Student(){}
     //带两个参数的构造方法
	 public Student(String name,int age){
	     this.name = name;
		 this.age = age;
	 }
     //为成员变量提供公共的赋值方法
	 public void setName(String name){
	    this.name = name;
	 }
	 public void setAge(int age){
	    this.age = age;
	 }
	 //为成员变量提供公共的获取方法
	 public String getName(){
	    return name;
	 }
	 public int getAge(){
	    return age;
	 }
     //普通方法
	 public void eat(){
	     System.out.println("人活着就为吃饭!");
	 }
     //学生属性的展示方法  
	 public void show(){
	    System.out.println(name+"-----"+age);
	 }
}
//测试类
class  StudentDemo{
	public static void main(String[] args) {
		//通过无参构造创建对象
		Student s = new Student();
		s.setName("梅梅");
		s.setAge(18);
		System.out.println(s.getName()+"---"+s.getAge());
        //通过带参构造创建对象
	    Student s2 = new Student("冬梅",19);
		s2.show();
	}
}

匿名对象:
 A:什么是匿名对象
              就是没有名字的对象
 B:匿名对象应用场景
              a:调用方法,仅仅只调用一次的时候。
             注意:调用多次的时候不适合.因为用一次就是创建了一个新的对象
             好处:匿名对象调用完毕之后就是垃圾,会被垃圾回收器回收.
             b:匿名对象可以作为实际参数传递   传递的时候实际是传递的内存中的地址值.
 案例演示

/*
  匿名对象:
     就是没有名字的对象

	 应用场景:
	   (1)通过匿名对象调用方法:
	      仅仅调用一次.调完就成了垃圾.
	   (2):匿名对象可以作为实际参数传递  
*/
class Student{
	String name;
	int age;

	public void show(){
	   System.out.println(name+"的年龄是:"+age);
	}
	public void eat(){
	   System.out.println("我就喜欢吃饭了!!最好是满汉全席");
	}
}
class StudentDemo{

	public void method(Student s){//new Student() 隐含了 Student s =  new Student();   
	   s.eat();
	}
}class NoNameDemo{
	public static void main(String[] args) {
		//创建对象
		/*
		Student s = new Student();
		s.name = "小芳" ;
		s.age = 18 ;
		s.show();
		//一个对象可以调一个方法多次
		s.eat();
		s.eat();

         System.out.println("--------------华丽分割线------------------");
		//匿名对象
        //每次调用都要创建新的对象.
        new Student().eat();
	    new Student().eat();
        System.out.println("--------------华丽分割线------------------");
		
		new Student().name = "张三";
        System.out.println(new Student().name);
        */
        StudentDemo  sd = new StudentDemo();
		
		//Student s = new Student();

		//sd.method(s);
		//用匿名对象作为实际参数传递
		sd.method(new Student());  
		
		
		new StudentDemo().method(new student());

	}
}


二,封装

1:封装概述
           是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
2:封装好处
           隐藏实现细节,提供公共的访问方式

           提高了代码的复用性
           提高安全性。
3:封装原则
           将不需要对外提供的内容都隐藏起来。
           把属性隐藏,提供公共方法对其访问。





B:封装概述
  是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
 C:封装好处
  隐藏实现细节,提供公共的访问方式
  提高了代码的复用性
  提高安全性。
 D:封装原则

  将不需要对外提供的内容都隐藏起来。
  把属性隐藏,提供公共方法对其访问。B:封装概述
  是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
 C:封装好处
  隐藏实现细节,提供公共的访问方式
  提高了代码的复用性
  提高安全性。
 D:封装原则
  将不需要对外提供的内容都隐藏起来。
  把属性隐藏,提供公共方法对其访问。 A:什么是匿名对象
  就是没有名字的对象
 B:匿名对象应用场景
  a:调用方法,仅仅只调用一次的时候。
             注意:调用多次的时候不适合.因为用一次就是创建了一个新的对象
             好处:匿名对象调用完毕之后就是垃圾,会被垃圾回收器回收.
  b:匿名对象可以作为实际参数传递   传递的时候实际是传递的内存中的地址值.
 C:案例演示
  匿名对象应用场景 A:什么是匿名对象
  就是没有名字的对象
 B:匿名对象应用场景
  a:调用方法,仅仅只调用一次的时候。
             注意:调用多次的时候不适合.因为用一次就是创建了一个新的对象
             好处:匿名对象调用完毕之后就是垃圾,会被垃圾回收器回收.

  b:匿名对象可以作为实际参数传递   传递的时候实际是传递的内存中的地址值.
 C:案例演示
  匿名对象应用场景 A:什么是匿名对象
  就是没有名字的对象
 B:匿名对象应用场景
  a:调用方法,仅仅只调用一次的时候。
             注意:调用多次的时候不适合.因为用一次就是创建了一个新的对象
             好处:匿名对象调用完毕之后就是垃圾,会被垃圾回收器回收.
  b:匿名对象可以作为实际参数传递   传递的时候实际是传递的内存中的地址值.
 C:案例演示
  匿名对象应用场景private(私有化)关键字特点
                             a:是一个权限修饰符
                             b:可以修饰成员变量和成员方法
                             c:被其修饰的成员只能在本类中被访问

private关键字实例,不带测试类:

/**
 *      A:private最常见的应用:
 *		(1):把成员变量用private修饰   把属性隐藏起来,提供公共方法对其访问。
 *		(2):提供对应的getXxx()和setXxx()方法  
 */
class Student{
	//把属性隐藏起来
	private String name;
	private int age;
	private String sex;
    //通过公共方法访问
	//setXxx()

    public void setName(String n){
	    name = n ;
	} 
	public void setAge(int a){
	    age = a;
	}
	public void setSex(String s){
	    sex = s ;
	}
    //getXxx()
	public String getName(){
	    return name;
	}
	public int getAge(){
	    return age;
	}
	public String getSex(){
	   return sex;
	}


	public void eat(){
	  System.out.println("你是个吃货,但是要学好java!");
	}

	public void sleep(){
	  System.out.println("休息好才能学习好!");
	}
}

创建一个对象到底需要哪些步骤:

步骤:
  (1):加载Student.class文件进内存
  (2):在栈内存为s开辟空间
  (3):在堆内存为学生对象开辟空间
  (4):对学生对象的成员变量进行默认初始化
  (5):对学生对象的成员变量进行显示初始化
  (6):通过构造方法对学生对象的成员变量赋值
  (7):学生对象初始化完毕,把对象地址赋值给s变量

如图所示:
步骤:
  (1):加载Student.class文件进内存
  (2):在栈内存为s开辟空间
  (3):在堆内存为学生对象开辟空间
  (4):对学生对象的成员变量进行默认初始化
  (5):对学生对象的成员变量进行显示初始化
  (6):通过构造方法对学生对象的成员变量赋值
  (7):学生对象初始化完毕,把对象地址赋值给s变量

this关键字:

一句话记忆,谁调用方法,this就指带的是谁。

 static关键字 :

A:static关键字的特点


  a:随着类的加载而加载
  b:优先于对象存在
  c:被类的所有对象共享


    举例:咱们班级的学生应该共用同一个班级编号。
    其实这个特点也是在告诉我们什么时候使用静态?
    如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
    举例:
    饮水机(用静态修饰)
    水杯(不能用静态修饰)
  d:可以通过类名调用
   其实它本身也可以通过对象名调用。
   推荐使用类名调用。
   静态修饰的内容一般我们称其为:与类相关的,类成员

因为static 加载的,优先于对象存在,所以 static关键字不能和this关键字共存

关于静态方法访问其他方法,有一个规律比较容易记住:

静态只能访问静态,非静态可以访问静态的也可以访问非静态的。

 

静态变量和成员变量的区别:

A:所属不同
  静态变量属于类,所以也称为类变量
  成员变量属于对象,所以也称为实例变量(对象变量)
 B:内存中位置不同
  静态变量存储于方法区的静态区
  成员变量存储于堆内存
 C:内存出现时间不同
  静态变量随着类的加载而加载,随着类的消失而消失
  成员变量随着对象的创建而存在,随着对象的消失而消失
 D:调用不同
  静态变量可以通过类名调用,也可以通过对象调用
  非静态变量只能通过对象名调用
 E:静态变量是对象的共享数据,非静态变量是对象的特有数据.

案例:

/**
 * static 注意事项:
 *    可以修饰成员变量也可以修饰成员方法
 *     A:静态成员中不能有this关键字:
 *	     怎么理解:
 *		    因为被static修饰的成员是随着类的加载而加载,优先于对象存在的
 *			this表示当前类的一个对象,它是跟着对象存在的.
 *	  B:静态只能访问静态:
 *	       
 *		      非静态方法: 成员变量                        成员方法:
 *			                非静态成员变量   可以               非静态成员方法   可以
 *			                静态成员变量     可以               静态成员方法     可以
 *							 
 *
 *			  静态方法: 成员变量                           成员方法
 *			                 非静态成员变量  不能               非静态成员方法  不可以
 *	                         静态成员变量     可以              静态成员方法     可以 
 *
 *
 *			  静态只能访问静态
 *							
 *	      
 */
class Teacher{
	//非静态成员变量
	String name = "张无忌";
    //静态成员变量
	static String menPai = "明教";
    
	//静态方法
	public static void method(){
	   //访问非静态成员变量
	   //System.out.println(name);//错误: 无法从静态上下文中引用非静态 变量 name
	   //访问静态成员变量
	   //System.out.println(menPai);
	   //访问非静态成员方法
	   //function();//错误: 无法从静态上下文中引用非静态 方法 function()
	   //访问静态成员方法
	   function2();
	}
	//非静态方法
	public void show(){
	   //System.out.println(name);
	   //System.out.println(menPai);
	   //访问非静态成员方法
	   function();
	   //访问静态成员方法
	   function2();
	}

    //静态方法
	public static void function2(){
	     System.out.println("我就是那个传说中的静态成员方法");
	}
	//非静态成员方法
    public void function(){
	     System.out.println("我就是那个非静态的成员方法");
	}
}
class TeacherDemo{
	public static void main(String[] args) {
		//创建对象
		Teacher t = new Teacher();
		//show()是一个非静态方法
		t.show();

		//调用Teacher静态成员方法
		Teacher.method();

	}
	
}

这个时候,我们就可以对之前学习控制台输出HelloWorld的案例的main方法进行一下格式的解释了:

  格式
  public static void main(String[] args) {}
  针对格式的解释
  public 被jvm调用,访问权限足够大。
  static 被jvm调用,不用创建对象,直接类名访问
  void    被jvm调用,不需要给jvm返回值
  main  一个通用的名称,虽然不是关键字,但是被jvm识别
  String[] args 以前用于接收键盘录入的

 

工具类概述

Arraytools工具类,直接调用static静态方法

 

说明书的制作过程,这里的知识属于了解部分

A:对工具类加入文档注释
  相关的一个参数执指定:
  @author  指定作者
  @version    指定版本
  @param      指定参数
  @return     指定返回值
 B:通过javadoc命令生成说明书
  通过javadoc工具解析对应的java源文件
  格式: javadoc -d 目录 -author -version 源文件名称.java
  目录: 就是指定说明文档要生成的对应的文件夹

 

阅读JDK帮助文档的方式(这个很重要,要贯穿以后java 学习):

A:找到文档,打开文档
B:点击显示,找到索引,出现输入框
C:你应该知道你找谁?举例:Scanner
D:看这个类的结构(需不需要导包)
java.lang包下的内容不需要我们手动导入
其他包下的类,需要导包
其它包下的内容需要我们手动导入
       类        API文档
成员变量    字段摘要
构造方法    构造方法摘要
成员方法    方法摘要
E:看这个类的说明(简单的了解一下)
F:看开始版本
G:看构造方法
    如果没有构造方法摘要,说明该类不能创建对象,它的方法只能是静态的,只能通过类名调用
H:看成员方法
   看左边:
   是否是static的,如果是我们就不需要创建对象,直接可以使用类名调用该方法;看返回值,返回值是什么我就使用什么接收
   看右边:
   看参数列表: 参数的个数 , 参数的类型 ; 要什么参数我是用的时候,就传递什么参数 ,看方法名,    
 I:然后使用

三,继承

一,在学习java继承的时候,先要学习一下代码块的知识

代码块概述
  在Java中,使用{}括起来的代码被称为代码块。
代码块分类
  根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。
常见代码块的应用
  a:局部代码块
   在方法中出现;限定变量生命周期,及早释放,提高内存利用率
  b:构造代码块
   在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
  c:静态代码块
   在类中方法外出现,加了static修饰
   在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。


以下是一道代码块的面试题

class Student {
			static {
				System.out.println("Student 静态代码块");
			}
			
			{
				System.out.println("Student 构造代码块");
			}
			
			public Student() {
				System.out.println("Student 构造方法");
			}
		}

		class StudentDemo {
			static {
				System.out.println("StudentDemo的静态代码块");
			}
			
			public static void main(String[] args) {
				System.out.println("我是main方法");
				
				Student s1 = new Student();
				Student s2 = new Student();
			}
		}

继承的概念:

A:继承概述
 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
 B:继承格式
 通过extends关键字可以实现类与类的继承
 class 子类名 extends 父类名 {}  
 单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类。
 有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员.

继承简单代码实例:

/*
  使用继承的好处:

     (1)提高代码的复用性
	 (2)提高代码的维护性
	 (3)让类与类之间产生了关系,这个是多态的前提

	 弊端:
	    我们开发有个原则:
		    高内聚,低耦合
			  一个类把事情都干了就不用麻烦别人了
			  尽量不要太复杂,你让这个类A与另一个类B产生关系,那天类B不高兴,这个类A是不是跟着不高兴
			内聚:某个类完成某个功能的能力
			    
			耦合:类与类之间关系  
*/
//用继承之前
/*
class Student{
	String name;
	int age;
	String sex;

	public void eat(){
	    System.out.println("吃饭!");
	}

	public void sleep(){
	    System.out.println("睡觉!");
	}
}
class Teacher{
	String name;
	int age;
	String sex;
    
	public void eat(){
	    System.out.println("吃饭!");
	}

	public void sleep(){
	    System.out.println("睡觉!");
	}
}
*/
/*
   使用继承怎么做
   将学生和老师 相同的代码提取出来放到一个独立的类中 这个类将来就是父类
   学生类 老师类 只需继承父类就可以
*/
class Person{
   String name;
   int age;
   String sex;

   public void eat(){
      System.out.println("吃饭");
   }

   public void sleep(){
      System.out.println("睡觉");
   }
}
class Student extends Person{}
class Teacher extends Person{}
class ExtendsDemo {
	public static void main(String[] args) {
		//创建学生对象
         Student s = new Student();
		 s.name = "马冬梅";
		 System.out.println(s.name);
		 s.eat();
		 s.sleep();

		 //老师对象
		 Teacher t = new Teacher();
		 t.name = "石破天";
         System.out.println(t.name);
         t.eat();
		 t.sleep();

	}
}


注意,java中只能单继承,不能多继承,可以多层继承!!!!!

a:子类只能继承父类所有非私有的成员(成员方法和成员变量)
b:子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
c:不要为了部分功能而去继承

成员变量的重名情况。就近原则。如果要区分,需要this关键字等!

二,this和super关键字:

A:通过问题引出super
  子类局部范围访问父类成员变量
 B:说说this和super的区别
  this代表的是本类对象的引用
  super代表的是父类存储空间的标识(可以理解成父类的引用,可以操作父类的成员)
 C:this和super的使用
  a:调用成员变量
  this.成员变量  调用本类的成员变量
  super.成员变量  调用父类的成员变量
  b:调用构造方法
  this(...)   调用本类的构造方法
  super(...)   调用父类的构造方法
  c:调用成员方法
  this.成员方法  调用本类的成员方法
  super.成员方法  调用父类的成员方法
 三,继承中构造方法的一些知识

子类中所有的构造方法默认都会访问父类中空参数的构造方法
:为什么呢?
因为子类会继承父类中的数据,可能还会使用父类的数据。
所以,子类初始化之前,一定要先完成父类数据的初始化。
  
其实:
每一个构造方法的第一条语句默认都是:super()

四,方法重写的案例:

A:什么是方法重写
  子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写。
B:方法重写的应用:
  当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
  这样,即沿袭了父类的功能,又定义了子类特有的内容。

方法重写注意事项
  a:父类中私有方法不能被重写
   因为父类私有方法子类根本就无法继承
  b:子类重写父类方法时,访问权限不能更低
   最好就一致
  c:父类静态方法,子类也必须通过静态方法进行重写
   其实这个算不上方法重写,但是现象确实如此
  子类重写父类方法的时候,最好声明一模一样。


/*
  A:方法重写
	
*/
class Father{
	public void show(){
	    System.out.println("show father!");
	}
	void method(){
	    System.out.println("method father!");
	}

	//父类有个静态的方法
	public static void function(){
	   System.out.println("父类中的静态方法!");  
	}
}
class Son extends Father{
	//我要重写父亲的方法
	public void show(){
	    System.out.println("show zi!");
	}

	public  void method(){
	    System.out.println("method zi!");
	} 
	/*
	//我子类想要重写父类的function()
	public  void function(){//Son中的function()无法覆盖Father中的function()
	   System.out.println("子类重写的function方法!");  
	}
	*/
    //我子类想要重写父类的function()
    public static void function(){
	   System.out.println("子类重写的静态方法!");  
	}

}
class ExtendsDemo10{
	public static void main(String[] args) {
        //创建子类对象
		Son s = new Son();
		s.show();
		s.method();
		Son.function();
	}
}


 五 final关键字 简述

A:为什么会有final
  由于继承中有一个方法重写的现象,而有时候我们不想让子类去重写父类的方法.这对这种情况java就给我们提供了一个关键字: final
 B:final概述
  final关键字是最终的意思,可以修饰类,变量,成员方法。

 B:final修饰特点
  修饰类:  被修饰类不能被继承
  修饰方法: 被修饰的方法不能被重写
  修饰变量: 被修饰的变量不能被重新赋值,因为这个量其实是一个常量

 
  基本类型,是值不能被改变
  引用类型,是地址值不能被改变

 

 C:final修饰变量的初始化时机
  a: 被final修饰的变量只能赋值一次
  b:在构造方法完毕前赋值即可(非静态的常量)

/*
  final关键字 修饰局部变量  
         被final修饰的变量叫做最终变量
         基本类型,是数值不能被改变
		 引用类型,是地址值不能被改变
*/
class Student{
	String name;
	int age;
	public void show(){
	  System.out.println(name+"----"+age);
	}
}
class FinalDemo3{
	public static void main(String[] args) {
		final int x = 10;
		System.out.println(x);
		//x = 20;//错误: 无法为最终变量x分配值
        //System.out.println(x);
		//引用数据类型
		Student s = new Student();
		System.out.println("s第一次的地址:"+s);
		s.name = "秋雅";
		s.age  = 20;
		s.show();
		s = new Student();
		System.out.println("s第二次的地址:"+s);
		System.out.println("-----------------");
		final Student s2 = new Student();//s2的值不能改   s2是什么值 地址值
		s2.name="夏洛";
		s2.age=34;
		s2.show();
		//s2 = new Student();//无法为最终变量s2分配值
	}
}

四,多态

什么是多态:某一个事物,在不同时刻表现出来的不同状态。  水(气态,液态,固态)

 

猫可以是猫的类型。猫 m = new 猫();
同时猫也是动物的一种,也可以把猫称为动物。动物 d = new 猫();

多态的前提:

a:要有继承关系。
b:要有方法重写。 其实没有也是可以的,但是如果没有这个就没有意义。
c:要有父类引用指向子类对象。

/*
   A:案例演示
		假如我们在开发一个系统时需要对员工(Employee)类进行设计,员工包含3个属性:姓名、工号以及工资(salary)。
		经理(Manager)也是员工,除了含有员工的属性外,另为还有一个奖金(bonus)属性。
		然后定义工作的方法.
        程序员Programmer
		请使用继承的思想设计出员工类和经理类。

  分析:
     从具体到抽象

     程序员: 姓名 工号 工资
	         工作 Coding
	 经理 :  姓名 工号 工资  奖金 
	         工作 lookYouCoding

	 提取公共的代码
	       成员变量: 姓名 工号 工资
		   构造方法: 无参 带参
		   成员方法 work (程序员与经理都工作,但是工作做的事不一样)
     父类起什么名字 员工 
实现:
   从抽象到具体
     Employee: 员工类 是抽象的
	    成员变量  name id salary
		构造方法 无参 带参
		成员方法 work---abstract

     Programmer:具体的类
	     构造方法:无参 带参
		 成员方法 work  ---(Coding)
	 Manager:具体的类
	     成员变量: bonus 奖金
		 构造方法 无参 带参
		 成员方法 work ---(lookYouCoding)
	     

*/
//定义一个员工类
abstract class Employee{
	private String name;
	private long id;
	private double salary;

	public Employee(){}

	public Employee(String name,long id ,double salary){
	    this.name = name;
		this.id = id;
		this.salary = salary;
	}
    
	public void setName(String name){
	   this.name = name;
	}
	public void setId(long id){
	   this.id = id;
	}
	public void setSalary(double salary){
	   this.salary = salary;
	}

	public String getName(){
		return name;	
	}
	public long getId(){
		return id;
	}
	public double getSalary(){
		return salary;
	}
   //抽象的工作方法
	public abstract void work();
}

class Programmer extends Employee{
	public Programmer(){}

	public Programmer(String name,long id ,double salary){
	    super(name,id,salary);
	}

	public void work(){
	    System.out.println("苦哈哈的Coding!");
	}
}
class Manager extends Employee{
	
	private double bonus;//经理特有的奖金
    
	public Manager(){}
	
	public Manager(String name,long id ,double salary,double bonus){
	     super(name,id,salary);
		 this.bonus = bonus;
	}
	public void setBonus(double bonus){
	     this.bonus = bonus;
	}
	public double getBonus(){
		return bonus;
	}
    public void work(){
	    System.out.println("笑哈哈的看着你苦哈哈的敲代码!");
	}

}
class AbstractTest2{
	public static void main(String[] args) {
		//使用多态创建对象
		Employee e = new Programmer("唐伯虎",9527,-10000);
		System.out.println("这个人是!"+e.getName());
		e.work();



	}
}

多态中访问的特点:


多态中的成员访问特点
  a:成员变量
   编译看左边,运行看左边。
  b:构造方法
   创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
  c:成员方法
   编译看左边,运行看右边。
  d:静态方法
   编译看左边,运行看左边。
   (静态和类相关,算不上重写,所以,访问还是左边的)

抽象类和抽象方法:

abstract关键字  表示抽象,可以修饰类又可以修饰方法
       抽象方法格式: public abstract 返回值类型 方法名();
       抽象方法: public abstract 返回值类型 方法名();

抽象类特点
  a:抽象类和抽象方法必须用abstract关键字修饰
   抽象类格式:  abstract class 类名 {}
   抽象方法格式: public abstract 返回值类型 方法名();
  b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
  c:抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?
   用于子类访问父类数据时的初始化
  d:抽象类不能实例化那么,抽象类如何实例化呢?
   按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
  e:抽象类的子类
   要么是抽象类
   要么重写抽象类中的所有抽象方法的具体类

抽象类的成员特点
  成员变量:既可以是变量,也可以是常量。
  构造方法:有。
     用于子类访问父类数据的初始化。
  成员方法:既可以是抽象的,也可以是非抽象的。
  抽象类的成员特点
抽象类的成员方法特性:
  抽象方法   强制要求子类做的事情。
  非抽象方法  子类继承的事情,提高代码复用性。

abstract不能和哪些关键字共存?private    冲突     final      冲突      static     无意义

接口的简单概述:

a:接口用关键字interface表示   格式:  interface 接口名 {}
b:类实现接口用implements表示  格式: class 类名  implements 接口名 {}
c:接口不能实例化
   那么,接口如何实例化呢?
   按照多态的方式来实例化。
d:接口的子类,也就是实现类
a:可以是抽象类。但是意义不大。
b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)

接口成员特点
    成员变量;只能是最终变量,并且是静态的。
    默认修饰符:public static final
            建议:自己手动给出。
    构造方法:接口没有构造方法。
    成员方法:只能是抽象方法。
          默认修饰符:public abstract
    建议:自己手动给出。

结尾:学完面向对象封装继承多态以后以后一个全案例:

public interface Japanese {
	public abstract void speakJapanese();
}
public abstract class Teacher {
	private String name;
	private int age;
	public Teacher() {
		super();
	}
	public Teacher(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public abstract void teach();
}
public class BaseTeacher extends Teacher {
	public BaseTeacher() {
	}
	public BaseTeacher(String name, int age) {
		super(name, age);
	}

	@Override
	public void teach() {
		System.out.println("Java基础课");
	}
}

public class JobTeacher extends Teacher {
	public JobTeacher() {
		super();
	}
	public JobTeacher(String name, int age) {
		super(name, age);
	}
	@Override
	public void teach() {
		System.out.println("Java就业课");
	}
}

public class SubBaseTeacher extends BaseTeacher implements Japanese {
	public SubBaseTeacher() {
		super();
	}
	public SubBaseTeacher(String name, int age) {
		super(name, age);
	}
	@Override
	public void speakJapanese() {
		System.out.println("用日语讲Java基础课");
	}
}

public class SubJobTeacher extends JobTeacher implements Japanese {

	public SubJobTeacher() {
		super();
	}
	public SubJobTeacher(String name, int age) {
		super(name, age);
	}
	@Override
	public void speakJapanese() {
		System.out.println("用日语讲Java就业课");
	}
}
class TeacherTest {
public static void main(String[] args) {
//测试
}
}

内部类简介:


 A:内部类概述:
           把类定义在其他类的内部,这个类就被称为内部类。
  举例:在类A中定义了一个类B,类B就是内部类。
 B:内部类访问特点
            a:内部类可以直接访问外部类的成员,包括私有。
            b:外部类要访问内部类的成员,必须创建对象。

匿名内部类:这个非常非常的常用!集合里面用匿名内部类做实现比较器,后面很多很多的代码都用匿名内部类简化写

                        A:匿名内部类:     就是内部类的简化写法。
                        B:前提:    存在一个类或者接口;这里的类可以是具体类也可以是抽象类。
                        C:格式:
                              new 类名或者接口名(){
                                重写方法;
                                   };
                        D:本质是什么呢?
                                是一个继承了该类或者实现了该接口的子类匿名对象。

/*
  匿名内部类 在开发中的应用
    匿名对象作为实际参数传递
  //按照我们之前的作法
    要写一个子类继承 抽象类

	是一个继承了该类的子类匿名对象。
*/
abstract class Person {
	public abstract void show();
}
/*
//创建一个学生类 继承 Person类
class Student extends Person{
	public void show(){
	    System.out.println("我就是爱学习,谁了拦不住我!!!");
	}
}
*/
class PersonDemo {
	public void method(Person p) {
		p.show();
	}
}

class PersonTest {
	public static void main(String[] args) {
		//如何调用PersonDemo中的method方法呢?
        /* 使用之前学习的方法做的
        //new PersonDemo().method(new Student());//里面传递的是一个抽象类的子类对象
		PersonDemo pd = new PersonDemo();
		Student s = new Student();
		pd.method(s);
		*/
		/*
		          new Person(){
		              public void show(){
					       System.out.println("我就是叶良辰,我就是爱学习");
					  }
		 
		          };  
				  上面那段代码相当于 new Student();
		*/
		//使用匿名内部类怎么做?
		PersonDemo pd = new PersonDemo();
		pd.method( new Person(){
		              public void show(){
					       System.out.println("我就是叶良辰,我就是爱学习");
					  }
		 
		          });//里面传递该类的子类匿名对象

	}
}


 




 

/*
  匿名内部类 在开发中的应用
    匿名对象作为实际参数传递
  //按照我们之前的作法
    要写一个子类继承 抽象类

	是一个继承了该类的子类匿名对象。
*/
abstract class Person {
	public abstract void show();
}
/*
//创建一个学生类 继承 Person类
class Student extends Person{
	public void show(){
	    System.out.println("我就是爱学习,谁了拦不住我!!!");
	}
}
*/
class PersonDemo {
	public void method(Person p) {
		p.show();
	}
}

class PersonTest {
	public static void main(String[] args) {
		//如何调用PersonDemo中的method方法呢?
        /* 使用之前学习的方法做的
        //new PersonDemo().method(new Student());//里面传递的是一个抽象类的子类对象
		PersonDemo pd = new PersonDemo();
		Student s = new Student();
		pd.method(s);
		*/
		/*
		          new Person(){
		              public void show(){
					       System.out.println("我就是叶良辰,我就是爱学习");
					  }
		 
		          };  
				  上面那段代码相当于 new Student();
		*/
		//使用匿名内部类怎么做?
		PersonDemo pd = new PersonDemo();
		pd.method( new Person(){
		              public void show(){
					       System.out.println("我就是叶良辰,我就是爱学习");
					  }
		 
		          });//里面传递该类的子类匿名对象

	}
}


A:匿名内部类:     就是内部类的简化写法。
 B:前提:    存在一个类或者接口;这里的类可以是具体类也可以是抽象类。
 C:格式:
  new 类名或者接口名(){
   重写方法;
  };
 D:本质是什么呢?
  是一个继承了该类或者实现了该接口的子类匿名对象。 A:内部类概述:
      把类定义在其他类的内部,这个类就被称为内部类。
  举例:在类A中定义了一个类B,类B就是内部类。
 B:内部类访问特点
  a:内部类可以直接访问外部类的成员,包括私有。
  b:外部类要访问内部类的成员,必须创建对象。 A:内部类概述:
      把类定义在其他类的内部,这个类就被称为内部类。
  举例:在类A中定义了一个类B,类B就是内部类。
 B:内部类访问特点
  a:内部类可以直接访问外部类的成员,包括私有。
  b:外部类要访问内部类的成员,必须创建对象。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值