java基础(二):面向对象

原创 2017年07月29日 21:10:13

一、成员变量和局部变量

    成员变量:作用于整个类中,存在于堆内存中,因为对象的存在,才在内存中存在。

    局部变量:作用于函数中,存在于栈内存中

二、封装

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

    好处:

        将变化隔离,便于使用,提高重用性,提高安全性

    封装原则:

        将不需要对外提供的内容都隐藏起来

        把属性隐藏,提供公共方法对其访问

        private修饰词修饰(权限修饰符,只能在本类中访问),提供get,set方法。用于修饰成员变量和成员函数。提高代码健壮性

    构造函数

        特点:函数名与类名相同,不用定义返回值类型,不可以写return语句

                    构造函数是在对象已建立就运行,给对象初始化,一个对象建立,构造函数只运行一次

        作用:给对象初始化

        注意:多个构造函数是以重载的形式存在的,

    构造代码块:

        作用:给对象进行初始化,对象一建立就运行,优先于构造函数执行

        和构造函数的区别:构造代码块是给所有对象进行统一初始化的,而构造函数是给对应的对象初始化的。

        注意:当一个类中每一个构造函数都要执行相同的初始化动作时,可以将这个初始化动作放到构造代码快中执行

    this关键字 :

        用于区分局部变量和成员变量同名的情况

        this代表本类对象,代表它所在函数所属对象的引用
        哪个对象在调用this所在的函数,this就代表哪个对象
        this语句(this(name);):用于构造函数间的调用,this语句只能放在构造函数的第一行

//例:
class Person{
    private String name;
    private int age;
    Person(){}
    Person(String name){
        this();
        this.name = name;
    }
    Person(String name,int age){
        this(name);
        this.age = age;
    }
}



        原因:假如在定义name的时候初始化了,private String name = "李四";
        构造函数:
            Person(String name){
                this.name = name;
                this();    
            }
            new Person(“张三”);
        一创建对象,会先给name属性赋值“张三”,然后再进行属性的显示初始化“李四”
        取得时候就取不到你初始化的值了。
        被修饰后的成员具备以下特点:
            随着类的加载而加载
                随着类的消失而消失,说明它的生命周期最长
            优先于对象存在
                静态优先存在,对象后存在
            被所有对象共享
            可以直接被类名调用
        注意:
            静态方法只能访问静态成员
            静态中不能写this和super关键字
            主函数是静态的
        调用方式:类名.静态成员。

    实例变量和类变量的区别

        1、存放位置:
            类变量随着类的加载而存在于方法去中
            实例变量随着对象的建立而存在于堆内存中
        2、生命周期
            类变量生命周期最长,随着类消失而消失
            实例变量生命周期随着对象的消失而消失       
        优缺点:
            优点:对对象的共享数据进行单独空间的存储,节省空间,可以直接被类名调用
            缺点:生命周期过长,访问出现局限性

    主函数:

        是一个特殊的函数,作为程序的入口,可以被jvm调用
        主函数的定义:
            public:代表该函数的访问权限最大
            static:主函数随着类的加载就存在了。
            void:没有返回值类型
            main:不是关键字,是个特殊的单词,可以被jvm识别
            (String[] args):函数的参数,
            格式固定:被jvm识别
        静态的使用:
            当方法不访问非静态成员变量时,可将方法静态化,

    静态代码块:

        只执行一次,优先主函数执行用于给类初始化
    对象创建过程:new一个对象:Person p = new Person();
        1、jvm加载类(Person.class)进内存,
        2、静态代码块执行,
        3、堆中开辟空间,分配内存地址值
        4、在堆内存中简历对象的特有属性,并进行默认初始化
        5、显示初始化(定义属性的时候赋的值),
        6、对对象进行构造代码初始化,
        7、构造函数初始化
        8、将内存地址值赋给栈内存中的p变量;

    被静态修饰的(成员方法或成员变量)优先对象存在于方法区中

//单例(static关键字的使用之一):
//饿汉式:
public class Single {
  private Single() {}
  private static Single s = new Single(); 
  public static Single getInstance() {
      return s;
  } 
}
//懒汉式:
public class Single { 
	private Single() {} 
	private static Single s = null; 
	public static Single getInstance() { 
		if (s == null) { 
			synchronized(Single.class) { 
				if (s == null) {
					s = new Single(); 
				} 
			} 
		} 
		return s; 
	}
}


java中的方法重写


什么是方法的重写: 
    如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用方法时会优先调用子类的方法。
    重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型。
    重写方法不能使用比被重写方法更严格的访问权限(由于多态)。
继承的初始化顺序


先初始化父类再初始化子类;
先执行初始化对象中的属性,再执行构造方法中的初始化。 
java中的final关键字的使用


final关键字做标识有“最终的”含义。
final可以修饰类、方法、属性和变量。 
    1.修饰类:则该类不允许被继承; 
    2.修饰方法:则该方法不允许被覆盖(重写); 
    3.修饰属性:则该类的属性不会进行隐式的初始化(类的初始化属性必须有值)或在构造方法中赋值; 
    4.修饰变量:则该变量的值只能赋一次值,即为常量。
Java中的super关键字的使用


    super关键字:在对象的内部使用,可以代表父类对象。  
    super的应用 
        1.子类的构造过程当中必须调用其父类的构造方法。 
        2.如果子类的构造方法当中没有显示调用父类的构造方法,则系统会默认调用父类无参的构造方法(通过super关键字)。 
        3.如果显示的调用构造方法,必须写在子类的构造方法的第一行(super();)。 
        4.如果子类构造方法中既没有显示调用父类的构造方法,而父类又没有无参的构造方法,则编译出错。
    java中的Object类

        Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object类。
    Object类中的方法,适合所有子类。
        几个重要的方法 
            1.toString()方法: 在Object类中定义toString()方法的时候,返回的是对象的哈希code码(对象地址字符串)。 可以通过重写toString()方法表示出对象的属性。 
            2.equals()方法: 比较的是对象的引用是否指向同一块内存地址。


    抽象练习2:模板方法模式

/*
* 雇员示例: 
* 需求:公司中程序员有姓名,工号,薪水,工作内容。 
* 项目经理除了有姓名,工号,薪水,还有奖金,工作内容。
* 对给出需求进行数据建模。
* 分析:
* 在这个问题领域中,先找出涉及的对象。 
* 通过名词提炼法。 
* 程序员: 属性:姓名,工号,薪水、 
*       行为:工作。 
* 经理: 属性:姓名,工号,薪水,奖金。
*       行为:工作。 
* 程序员和经理不存在着直接继承关系, 但是程序员和经理却具有共性内容。
* 可以进行抽取。因为他们都是公司的雇员
* 可以将程序员和经理进行抽取.建立体系.
*/
//描述雇员。
abstract class Employee {
	private String name;
	private String id;
	private double pay;
	Employee(String name, String id, double pay) {
		this.name = name;
		this.id = id;
		this.pay = pay;
	}
	public abstract void work();
	// getter setter
}
// 描述程序员。
class Programmer extends Employee {
	Programmer(String name, String id, double pay) {
		super(name, id, pay);
	}
	public void work() {
		System.out.println("programmer work");
	}
}
// 描述经理。
class Manager extends Employee {
	private int bonus;
	Manager(String name, String id, double pay, int bonus) {
		super(name, id, pay);
		this.bonus = bonus;
	}
	public void work() {
		System.out.println("manager work");
	}
	// getter setter
}

    static关键字:用于修饰成员(成员变量和成员函数)

三、继承

    特点:

         类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模。
         提高代码的复用性。子类继承父类,可以得到父类的全部属性和方法(除了父类中的构造方法)。
         java中只有单继承,没有像c++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。
         java中的多继承可以通过接口来实现。 
        提高代码复用性,让类之间产生关系,多态的体现,只支持单继承(接口支持多继承)

//例:
class A{
void show(){}
}
class B{
void show(){}
} 
class c extends A,B{

}
class Test{
	public static void main(String[] args){
		new C().show();//这里就挂了,不知道调用那个方法了
	}
}

    重写(函数):

        与父类方法同名,同返回值类型,同形式参数,访问权限等于或者大于父类方法的权限,静态只能覆盖静态

    重载和重写的区别:

        重载:只看同名函数的参数列表
        重写:子父类方法要一样(除了里面的逻辑代码)
        super的用法,调用父类一般函数:super.函数名;调用父类构造函数:super();
        super语句必须定义在子类的第一行;
    子类构造函数中super和this语句只能只有一个;
        子类的所有构造函数都会默认访问父类的空参数构造函数(子类所有构造函数第一行都有一句隐式的super();)
        父类中没有空参数的构造函数时,子类必须显示的通过super语句访问父类的构造函数
        子类中至少会有一个构造函数访问父类的构造函数

    问:为什么super和this在构造函数中只能写第一行
         因为初始化动作要先执行

四、抽象

    特点:

        抽象方法一定在抽象类中。
        抽象方法和抽象类都必须被abstract关键字修饰
        抽象类不能创建对象
        抽象类中的方法要被使用,必须有子类复写所有的抽象方法后建立自雷对象调用,如果子类只覆盖了部分抽象方法,那么子类还是一个抽象类

    抽象练习:

/*
 * 需求:获取一段程序运行时间 
 * 原理:获取程序开始和结束时间并相减
 */
abstract class GetTime {
	public final long getTime() {
		long start = System.currentTimeMillis();
		runCode();
		long end = System.currentTimeMillis();
		return end - start;
	}
	public abstract void runCode();// 让子类做想做的事情,不一定要抽象,可以有默认的方法
}
class SubTime extends GetTime {
	@Override
	public void runCode() {// 方法内的代码自定义
		try {
			Thread.sleep(5245);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("SubTime");
	}
	public static void main(String[] args) {
		SubTime st = new SubTime();
		System.out.println(st.getTime());
	}
}

    接口:

        定义:
            当抽象类的方法都是抽象的,那么这个类可以通过接口的形式来表示
            class:用于定义类
            interface用于定义接口
            子类必须全部覆盖接口方法才能实例化
            一个类可以实现多个接口(就算两个接口中有相同的抽象方法【完全相同,包括返回值和方法名】也可以),并且可以同时实现继承
            接口和接口之间可以实现多继承(注意:当两个接口中有两个抽象方法的方法名相同但是返回值不同的时候,这两个方法要符合重载的形式否则编译失败)

//例:
interface A {
	public abstract int show();
}
interface B {
	public abstract double show();
}
interface C extends A,B{
//此时,编译失败
//如果A接口和B接口方法名相同,那么可以将两个抽象方法定义到一个接口里,使用重载的形式使其存在
}


        接口定义的格式特点:
            接口中常见的定义:常量,抽象方法,静态方法(jdk8才有)
            接口中的成员都有固定的修饰符:
                常量:public static final 类型  名称(名称所有字母大写)
                方法:public abstract 返回值  方法名();
                静态方法:public static 返回值  方法名() {}
        接口的使用:
            类实现接口使用implements关键字,支持类多实现接口,但是只能单继承,如果这个类没有全部实现接口的方法,则这个类是抽象类
            接口之间的继承使用extends关键字,接口之间支持多继承。
        接口的特点
            接口是对外暴露的规则
            接口是程序的功能扩展
            接口可以用来多实现
            类与接口之间是实现关系(implements),而且类可以继承一个类的同事实现多个接口
            接口和接口之间可以有多继承关系

五、多态

    体现:

         父类引用指向了自己的子类对象
         父类的引用也可以接受自己的子类对象

    前提

        必须是类与类之间有关系,要么继承要么实现
        通常还有一个前提:存在覆盖

    好处

        多态的出现大大的提高了程序的扩展性

    弊端

        提高了扩展性,但是只能使用父类的引用访问父类中的成员
        //Animal a = new Cat(); //类型提升,向上转型
        如果想要提升类型,向下转型 Cat c = (Cat)a;

    多态中成员的特点:

        在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有编译通过,没有则编译失败
        在运行时期:参阅对象所属的类中是否有调用的方法
        简单总结就是:成员函数在多态调用时,编译看左边,运行看右边
            多态中,成员变量的特点:无论编译还是运行,都参考左边(引用型变量所属的类)
            多态中,静态成员函数的特点:无论编译,运行,都参考左边
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

贪吃蛇源代码『最近写的一个JAVA小游戏』,整体构思过程如文

项目主要是写四个类分别为:Yard(画出蛇移动的区域),Snake(定义蛇的相关属性和行为),Egg(蛋的属性以及相关的行为)。 1.在Yard类中写好:main(),Launch(),paint()...

java面向对象面试题(2)

1) 给定如下java代码程序片断:        class A{               public A(){                      System.out...

Java4Android 13_面向对象基础(二)

  • 2014年09月07日 10:03
  • 14.79MB
  • 下载

黑马程序员——Java基础:面向对象一些概念的区分(二)

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——- 14.static的应用 1)工具类的对象中并未封装特有数据,成员方法也没有用到对象的 特有数据,...

java基础——面向对象(二)

一、      继承(extends) 继承的好处:提高了代码的复用性,让类与类之间产生了关系,有了这个关系才有了多特的特性 号外:千万不要为了获取其他类的功能而去继承,必须是有类与类之间有所属关系(...

Java面向对象基础(二)

### 1.构造器: 1. 构造函数在一个类没有写任何的构造函数的时候,系统会生成一个默认的空参数构造函数,这个构造函数的修饰符就是类的修饰符,当我们定义了一个构造函数,默认的构造函数就不存在了而不会...

Java基础之面向对象(二)--static、静态代码块、Main函数、单例模式

/* 静态:static。 用法:是一个修饰符,用于修饰成员(成员变量,成员函数). 当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外, 还可以直接被类名调用。类名.静态成员。 sta...

黑马程序员——Java基础---面向对象(二)

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-一.对象初始化过程根据下面代码的运行结果来去说明对象初始化过程 运行结果: Person p = ne...

黑马程序员---java基础知识之面向对象(二)

java基础知识之面向对象(三)

黑马程序员_java基础3-面向对象(二)多态、异常、包

------- android培训、java培训、期待与您交流! ---------- (day08)面对对象(二)*****************************************...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java基础(二):面向对象
举报原因:
原因补充:

(最多只允许输入30个字)