黑马程序员--java面向对象

------- android培训java培训、期待与您交流! ----------

java基础之面向对象

面向对象是一种常见的程序结构设计方法。
面向对象思想的基础是将相关的数据和方法放在一起,组合成一种新的复合数据类型,然后使用新创建的复合数据类型作为项目的基础。

面向对象是一个很抽象的概念,它相对面向过程而言。

过程与对象都是一种解决问题的思想。

面向过程:强调的是功能行为,一种过程,先干啥,再干啥;

面向对象:将功能封装到对象里,强调的是具备某功能的对象;

按照面向对象的思想,可以把任何的东西看做对象!

用java语言写程序,其实就是找对象用,没有合适对象就创建对象。过程就是,找对象,建对象,用对象,维护对象间关系。

 

1.类和对象的关系:

类是对现实生活中某类型事物的描述,描述这类事物应该有什么共性(属性和行为),对象是这类事物的一个具体实例,可以拥有描述中所有共性的具体内容(属性值和可以执行的方法,方法被调用时才运行)。

2.想要使用对象,必须先创建对象:

从类中new出来一个对象放到堆内存中,如Person p = new Person( );过程:在堆内存中开辟个内存空间存放对象实体,封装了对象所属类的所有属性(属性值看具体初始化的方式),对象的内存地址让一个变量p存储,p是在栈内存中。p中存储的是对象实体的地址值,p指向对象实体,我们说,p是对象的引用,使用p可以操作对象的所有属性和方法。对象一旦创建就会一直存在,除非没有引用指向它了,那么,它随时可能被java垃圾回收机制回收,即释放对象所使用的内存。而引用可以接收其他对象地址值,重新指向其他对象,当它不再指向任何对象时,就会被释放。

3.成员变量和局部变量

在内存中存储区域不同:成员变量在栈内存中,因对象存在而存在。局部变量在栈内存中。

作用范围不同:成员变量定义在类中作用于整个类,局部变量定义在方法或语句中,作用于方法体内或语句块中(所在大括号内)

4.匿名对象

匿名对象就是没有名字(没有引用指向)的对象

有两种使用场景:

第一种,对对象方法(访问属性没意义)只进行一次调用;

第二种,作为对象方法的实际参数进行传递;参数名(栈中)指向对象(堆中),方法结束,对象成垃圾;

5.封装

java语言的特性之一,指的是隐藏对象的属性和实现细节,只对外提供公共访问方式

好处:将变化隔离,便于使用;提供复用性和安全性。

封装原则:把不需要对外提供的内容都隐藏起来(类,方法,对象都是封装体),把对象的属性都隐藏(私有化),仅对外提供公共访问方式。

注意:java提供了很多现成的类供我们使用,只知道如何使用就行,不需要知道其内部原理,但为了以后我们自己创建类,还是要知道其内部原理的。

私有是封装的多种表现形式中的一种,通过权限修饰符private实现,private修饰成员(成员变量和成员方法),把成员封装到类中,对外提供访问方式,对数据访问进行控制,提高代码健壮性。

6.构造函数

用来初始化对象的函数

特征:与类同名,没有返回值(没有void,也没有return

每个类中都有一个默认空参数的构造函数,如果自己定义了构造函数,那么系统就不再提供默认的空参数构造函数了。

一个类中可以定义多个构造函数,但是参数列表必须不同,这些构造函数构成了函数的重载。重载,是指在一个类中有多个同名函数存在,但是参数列表不同(参数类型,参数个数)。

构造代码块,就是类中用大括号括起来的一个代码块,用来初始化所有对象。对象一旦创建,先执行构造代码块初始化,后执行构造函数初始化。

7.this关键字

具体应用场景:

一、定义类中功能时,本类中函数用到调用该函数的对象时,this指代该对象的引用:例如,构造函数中成员变量和局部变量(参数)同名

二、this语句可以用来进行构造函数间调用,必须放在构造函数中的第一行

10.static关键字

static是静态修饰符,修饰成员(成员变量和成员方法)。

当类中所有的对象拥有相同的数据时,这样的数据没必要在对象都单独存储一份,用static修饰后,会在方法区(数据区,共享区)存储一份,供对象使用。

static修饰的成员特点:

一、随着类的加载而加载,随着类的消失而消失。生命周期很长。

二、优先于对象存在

三、被所有对象共享

四、可以直接被类名调用

static修饰的静态成员变量称为类变量,非静态成员变量称为实例变量,区别:

1)、存放位置不同:

静态变量随着类的加载而存在于方法区

实例变量随着对象的创建而存在于堆内存中

2)、生命周期不同:

静态变量随着类的加载而加载,类的消失而消失,生命周期很长。

实例变量随着对象的创建而存在,随着对象的消失而消失。

静态使用注意:

1)、静态只能访问静态,非静态既可以访问静态也可以访问非静态

2)、静态方法中不能有thissuper关键字,因为静态方法存在时还没有对象

3)、主函数是静态的

(其实也就三点:加载顺序(静态随类加载时对象还没存在,所以静态只能访问静态),存放位置(决定了生命周期),生命周期)

怎样使用静态?

因为静态可以修饰成员变量和成员方法,所以从两个方面下手:

什么时候定义静态变量呢?

当类中对象有共享的数据时,这些数据定义为静态,具体对象拥有的特有数据定义为非静态

什么时候定义静态方法呢?

当方法中没有访问到非静态数据(对象的特有数据)时定义为静态方法

例如,工具类,类中的方法一般只接收调用者传递的数据,没有类就实例的特有数据,所以定义为静态方法,不需要创建对象,直接类名调用即可。工具类中有很多方法,而有些方法是为类中其他方法使用的,不需要对外提供访问方式,就私有化。

11.对象初始化的过程:Person p = new Person( )

1)、将Person.class加载进内存,因为new Person()用到Person.class

2)、执行静态代码块,初始化类

3)、在堆内存中开辟空间,分配内存地址

4)、在分配的内存中建立对象特有属性,并默认初始化

5)、对对象特有属性显示初始化

6)、构造代码块初始化

7)、构造函数初始化

8)、将内存地址赋给栈内存中的变量p

12.对象调用方法的过程

jvm虚拟机调用main方法,main方法进栈

对象或类调用方法,在栈中开辟内存空间,方法从方法区进栈

方法执行完毕,内存释放

方法没被调用时就在方法区呆着,被调用时才进栈执行,执行完就从栈中消失。

13.单例设计模式

就是让一个类在内存中只能存在一个对象

思路:不允许类外创建对象,类中创建对象并对外提供对象获取方法

私有化构造方法,创建对象(或引用),对外提供获取对象方法。

//懒汉式单例设计模式
public class Single {

	public static void main(String[] args) {
		
	}
	static private Single single = null;
	private Single(){
		
	}
	public static Single getInstance(){
		if(single==null)
			synchronized(Single.class){
				if(single == null)
					single = new Single();
			}
		return single;
	}
}

注意:单例只是保证对象在内存中的唯一性,类该怎么描述还怎么描述,只是加上三步

14.继承

概述:现实中,一些类之间存在一些相同的描述,把这些相同的描述抽取出来封装成类,那么之前的那些类和这个类就有了关系--继承。java中是先有父类,后有子类。

单继承:一个类只能继承一个父类。这样是为了降低类与类之间关系的复杂性

多层继承:父类可以派生子类,子类还可以有自己的子类,以此类推,就构成了一个继承体系。父类定义的是基本的共性内容,子类除了有父类的共性内容还有自己特有的内容。所以,使用继承体系时先了解父类再了解子类。

子父类中成员(变量、方法和构造方法)的关系:

1)、成员变量

子类继承了父类所有的非私有成员变量,子类对象可直接使用。当子类中成员变量和父类中非私有成员变量名相同时,想使用父类的变量用关键字super,想使用子类的变量用关键字this

super指代父类对象的引用,this指代子类对象的引用

2)、成员方法

子类继承了父类所有的非私有成员方法,子类对象可以直接调用。如果子类中定义了和父类中相同的方法(同名同参数列表同返回值类型),那么子类对象调用的是子类的方法,因为子类方法覆盖(重写)了父类方法。

重写:子父类方法的功能相同,实现内容不同

      子类方法重写父类方法,子类方法权限大于等于父类方法权限

      静态只能重写静态

3)、构造方法

子类不能继承父类的构造方法,但当子类创建对象并初始化时必须先访问父类的构造方法,因为所有的子类构造方法中第一行有个默认的父类空参数构造方法:super()。

为什么呢?

因为子类对象可以直接获取父类的数据,那么子类对象初始化时应该先执行父类对数据的初始化,才能获取父类的数据。

如果父类中没有了默认的空参数构造函数,那么子类构造函数中必须在第一行指定执行的父类构造函数

子类的构造函数中第一行也可以使用this语句访问本类的构造函数

此时this语句和super语句不能同时出现

15.final关键字

1)、final作为修饰符可以修饰类、函数和变量

2)、final修饰类时,这个类是最终类,不允许被继承

3)、final修饰函数时,这个函数不允许被复写

4)、final可以修饰成员变量和局部变量,被final修饰的变量是常量,只能被赋值一次,不允许修改。作为常量,符合常量书写规范

16.抽象类

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

抽象方法:当多个类中有相同的功能定义,但功能主体不同,这时可以将相同的功能定义抽取,但不定义功能主体,那么这个方法就是抽象方法,用abstract修饰

1)、抽象方法必须放在抽象类中,都用abstract修饰

2)、抽象类不可以new对象,因为对象调用抽象方法没意义

3)、要想使用抽象类中的方法,必须由其子类复写全部抽象方法,由子类对象调用

抽象类和一般类的区别不过是多了抽象方法,不能创建对象罢了,该怎么描述还怎么描述

17.模板方法设计模式

当定义一个功能时,有些代码是确定的,有些代码是不确定的,而确定的代码在使用不确定的代码,那么就将不确定的代码暴露出去,让它的子类去完成。

/*
 * 需求:获取一段程序运行的时间。 原理:获取程序开始和结束的时间并相减即可。
 * 获取时间:System.currentTimeMillis();
 */

abstract class GetTime {
	public final void getTime() {
		long start = System.currentTimeMillis();
		runcode();
		long end = System.currentTimeMillis();

		System.out.println("毫秒:" + (end - start));
	}

	public abstract void runcode();
}

class SubTime extends GetTime {

	public void runcode() {

		for (int x = 0; x < 4000; x++) {
			System.out.print(x);
		}
	}
}

class TemplateDemo {
	public static void main(String[] args) {
		// GetTime gt = new GetTime();
		SubTime gt = new SubTime();
		gt.getTime();
	}
}

18.接口

初期理解:有抽象方法的类是抽象类,当类中的方法都是抽象方法时就成了接口了。

1)、接口中常定义常量和抽象函数

2)、常量和函数有默认固定的修饰符:

public static final int NUM=9

public abstract void method();

1)、接口不能创建对象

2)、接口需要被子类实现其全部抽象方法才能创建子类对象,否则子类是一个抽象类

3)、java支持接口多实现:一个类可以实现多个接口

一个类不可以继承多个类,是因为多个类中的方法可能会有重复,子类不知道调用哪一个。而接口中的方法都没有方法体,全部需要子类实现,不会有冲突。

1)、接口之间支持多继承

2)、接口可以看作类的继承体系的一种功能扩展或补充

19.多态

可以理解为事物的多种体现形态。比如,动物:猫、狗,一个具体的猫可以叫他猫,也可以叫他动物。

1)、多态的体现:

父类引用指向了子类对象

父类引用也可以接受本类对象

2)、多态的前提:

类与类直接必须有关系,要么继承,要么实现

通常还存在覆盖

3)、多态的好处:

大大提高了程序的扩展性

4)、多态的弊端:

父类的引用虽然指向子类对象,但只能访问父类的内容

5)、如何使用子类特有方法:

让父类的引用指向子类对象,是为了方便访问父类方法,与具体对象无关,无法访问子类对象的特有方法。如果想访问子类对象的特有方法,必须将父类的引用强制转型为子类类型。强制转型时先判断父类引用指向的对象是不是子类的实例,因为如果父类引用指向的是父类的对象的话是不能强制转型的。

6)、多态的应用:

父类中有一些方法,子类继承了也可能复写了父类的方法,子类会有很多个,当子类对象使用父类定义的功能时,先创建本类对象,再调用父类的或被子类复写了的方法,多个子类时,需要创建多个对象,扩展性差。可以这样,将父类中定义的功能封装成工具类,功能方法的形参为父类型,这样可以接收父类所有子类的对象,子类对象就可以调用父类中定义的子类中的具体方法了。

20.Object

java中所有类的直接或间接父类,也就是java的根类。传说中的上帝。

Object类中定义的方法是所有类共有的最基础的方法,例如,equals方法,toString方法等,子类使用时可以根据自己的需要进行复写。

21.内部类

定义在类里面的类

内部类可以直接访问外部类的成员

外部类访问内部类成员,必须先建立内部类对象:

Out.In in = new Out().new In();

in.内部类成员名

/*
内部类的访问规则:
1,内部类可以直接访问外部类中的成员,包括私有。
	之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2,外部类要访问内部类,必须建立内部类对象。
*/
class Outer{
	private int x = 3;
	
	class Inner{
		//int x = 4;
		void function()
		{
			//int x = 6;
			System.out.println("innner :"+Outer.this.x);
		}
	}

	void method()
	{
		Inner in = new Inner();
		in.function();
	}
}

class  InnerClassDemo{
	public static void main(String[] args) {
		Outer out = new Outer();
		out.method();

		//直接访问内部类中的成员。
//		Outer.Inner in = new Outer().new Inner();
//		in.function();
	}
}

匿名内部类:

/*	
匿名内部类:
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
	内部类必须是继承一个类或者实现接口。
3,匿名内部类的格式:  new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。	可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个。
*/
abstract class AbsDemo{
	
	abstract void show();
}

class Outer{
	int x = 3;
	class Inner extends AbsDemo{
		int num = 90;
		void show()
		{
			System.out.println("show :"+num);
		}
		void abc()
		{
			System.out.println("hehe");
		}
	}
	public void function(){
		//AbsDemo a = new Inner();
//		Inner in = new Inner();
//		in.show();
//		in.abc();
		AbsDemo d = new AbsDemo(){
			int num = 9;
			void show(){
				System.out.println("num==="+num);
			}
            void abc(){
				System.out.println("haha");
			}
		};
		d.show();
		//d.abc();//编译失败;
	}
}
class InnerClassDemo{
	
	public static void main(String[] args) {
		new Outer().function();
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值