JavaSE(二)面向对象

1.创建一个类

class Servant   //创建一个类
{
	String name;
	int age;
	void shopping()
	{
		System.out.println("出门购物");
	}
	void cook()
	{
		System.out.println("赶紧去做饭");
	}
	void eat()
	{
		System.out.println("可以吃饭啦");
	}
	void wash()
	{
		System.out.println("洗碗吧");
	}
}

2.创建一个对象
对象:类(抽象)的实例化(个体)
类 对象名 = new 类名();
没有名字的对象,就是创建对象时,没有赋给一个变量.
new Servant();创建一个匿名对象
匿名对象只能使用一次,就是被创建的这一次
在这里插入图片描述
3.构造器
主要用于创建对象并返回对象和初始化对象数据.
构造器的特点:
类都有一个默认构造器,当不显示的定义构造器的时候,编译器会在编译的时候,提供一个默认构造器.
1):构造器的名字必须和当前所在类的类名相同.
2):不需要定义返回值类型,更加不能使用void作为返回.构造器的目的在于创建和返回当前类的对象,即使要编写返回类型,也应该是当前类名,如:Student Student(){},既然和当前类名相同,就规定统统省略.
3):构造器中不需要使用return来返回当前构造的对象.
构造器重载:
不同类的构造器是不相同的. 对于构造器重载来说,肯定是在同一个类中,并且构造器都是和类名相同.
所以在同一个类中的多个构造器就必须参数列表不同(参数类型,参数个数,参数顺序).
在这里插入图片描述

class Person  //创建一个Person类 ,表示人类
{
	String name =null; 
//自定义一个构造器 ,构造器的作用是创建一个对象,并且完成对象的初始化操作


	Person(String n) //带有参数的构造器,底下创建对象的时候也要有参数
	{
		name = n; //将n的参数赋值给name
		//初始化操作,可以字段赋值,也可以调用初始化方法
	}
	Person() //构造器的重载 , 两同一不同
	{
		System.out.println("无参数");
	}


}
class PersonDemo
{
	public static void main(String[] args)
	{
		Person p = new Person("程序猿"); //如果为Person p = new Person();报错, 构造器带有参数
		System.out.println(p.name);


		Person p1= new Person();  // 不带参数
		p1.name = "单身狗";
		System.out.println(p1.name);
	}

}

4.static
static可以修饰成员变量(字段),可以修饰方法等,就表面该字段或该方法属于类,而不属于某一个对象
类成员(static修饰成员)的特点:
1):随着类被加载进JVM而同时也最初始化和在内存中分配空间.
2):优先于对象存在.(对象是通过new出来的.)
3):被该类的所有对象所共享.
该状态/行为是整个人类的,那么每一个人都是拥有该状态/行为的.
4):直接使用类名调用即可.
人类毁灭: Person.destory();
类 成员:使用static修饰的成员变量/方法,属于类,所以可以直接使用类名访问.
实例成员:没有使用static修饰的成员变量/方法,属于对象.必须使用对象来访问.
访问规则:
1):静态方法只能访问静态的成员变量/方法,不能访问非静态的成员变量/方法(属于对象).
静态成员优先于对象存在.
2):非静态方法可以访问非静态成员变量/方法,也可以访问静态的成员变量/方法.
因为底层使用对象访问的.
3):对象可以访问静态成员,但是不推荐,因为底层依然使用类名在调用.
4):类可以访问静态成员,类不能访问非静态成员(成员变量/方法).

class Person //定义一个类.  表示人类
{
	String name = null;	
	static int totalnum = 10; // 表示人类的总人数 ,属于整个人类 不属于对象
	Person(String a) //创建一个对象  方法名和类名一致
	{
		name = a ;
		totalnum ++;
		System.out.println(name + "从石头缝里蹦出来");
		System.out.println("人类总人数:" + totalnum);
	}
	
	
	void die(String a ) //表示某个人挂了, 不表示人类挂了
	{
		name = a ;
		totalnum --;
		System.out.println(name + "挂了..");
		System.out.println("人类总人数:" + totalnum);
	}
	static void destory() //表示人类灭绝了  ,不表示某个对象灭绝了
	{
		//String n = name;  //此处报错,无法从静态上下文引用非静态变量 name  (name是属于实例成员)
		totalnum = 0;
		System.out.println("全挂了~~~~");
	}
}
class PersonStaticDemo
{
	public static void main(String[] args)
	{	
		// String x = Person.name;
		//System.out.println(Person.name);
		Person p1 = new Person("张大猪");
		Person p2 = new Person("张二猪");
		System.out.println(Person.totalnum); //直接使用类名访问static成员
		p1.die("张小猪");
		Person.destory();


		
	}
}

5.四大访问权限
① private(类访问权限):使用private修饰的成员(字段,方法,构造器),就只能在当前类中范围.
② 什么都不写(缺省/包访问权限):此时只有在同一个包中,才可以访问的到,若不在同包中,不能访问.
③ protected(子类访问权限):即使父类和子类不在同一个包中,也可以访问.
④ public(公共访问权限):在任何地方都可以访问到

class Person
{
	String name;   //系统默认值  name = null ;
	private int age ;    //默认值为 0
	
	

	public int getAge()   //getter 无参数有反悔
	{
		return age;
	}
	public void setAge( int a)  //有参数无返回
	{
		if (a < 0)
		{
			System.out.println("你484sa ,年龄不能为负数");
			return;
		}
		age = a;
	}
	
}
class PersonDemo
{
	public static void main(String[] args)
	{
		Person p = new Person();
		p.name = "lucy";
		p.setAge(20);
		int ret = p.getAge();
		System.out.println(p.name +"," + ret);
		//System.out.println(p.name +"," + p.age);  //若上述 age 用 private 修饰 ,则此句报错
		Person p1 = new Person();
		p1.name = "candy";
		p1.setAge(-7);
		//System.out.println(p1.name +"," + p1.age); //此处age为系统默认值
	}
}

被private修饰的话,对象都不能访问
6.this
使用this的场景:

① 解决成员变量和局部变量之间的二义性,必须使用;(setter方法)
② 同一个类中多个实例方法间互调。

③ 将当前对象作为参数传递给另一个方法;

④ 讲当前对象作为方法的返回值(链式方法编程);

⑤ 构造器重载的互调,this([参数])必须写在构造方法第一行;
在这里插入图片描述
7.继承
子类可以继承到父类哪些成员:
1):若父类成员使用public或者protected修饰,子类可以继承.
2):若父类成员使用包访问权限(不写):
若子类和父类在同包中,可以继承.
若子类和父类不在同包中,则不能继承.

3):若父类成员使用private修饰,子类不能继承.
4):父类的构造器,子类也继承不到.
在这里插入图片描述
8.方法重写
用于子类不适用从父类继承方法的情况

class Bird
{
	 public void fly()
	{
		System.out.println("飞翔");
	}
}

class Penguin extends Bird
{
	 public void fly()
	{
		//方法签名和Bird 一样
		System.out.println("断翅,不能飞");
	}
}


class OverrrideDemo 
{
	public static void main(String[] args) 
	{
		//System.out.println("Hello World!");
		new Penguin().fly();//创建一个对象访问方法

	}
}

在这里插入图片描述
9.super
用于方法被重写但仍要调用父类的方法的时候

class Bird extends Object //等价于class Bird
{
	public void fly()
	{
		System.out.println("飞啊飞啊飞啊");
	}
}
class Penguin extends Bird
{
	public void fly()
	{
		System.out.println("断翅,不能飞了");
	}
	public void sing()    //使用关键字super调用父类中的方法
	{
		System.out.println("但是我会唱歌啊啊啊");
		super.fly(); //super当前对象的父类对象 ,表示到父类对象中寻找fly方法
		// this.fly()  表示寻找当前对象的方法
		// super.fly() 表示寻找父类对象的方法
	}
}

class SupDemo 
{
	public static void main(String[] args) 
	{
		new Penguin().sing();
	}
}

在这里插入图片描述
10.多态
把子类对象赋给父类的变量,一个对象可以有多种形态.
在这里插入图片描述
11.静态代码块
使用static修饰的初始化代码块.
当静态代码块所在类的字节码被加载进JVM,就立马执行静态代码块,而且只会执行一次.
一般的,做静态资源的初始化,加载文件,加载资源.
静态代码块优先于main方法执行.
----->main方法,是在字节码被加载进JVM之后,再调用的.

class  CodeBlockDemo
{
	{
		System.out.println("初始化模块");//创建对象时候在底层里面是作为构造器的最初语句
	}
	
	CodeBlockDemo()
	{
		System.out.println("构造器模块"); 
	}
	static
	{
		System.out.println("静态初始化模块");  //static 随着jvm的加载而加载,此时main方法还没执行,所以是第一个输出
	}
	public static void main(String[] args) 
	{
		System.out.println("main方法入入口");
		new CodeBlockDemo();
		new CodeBlockDemo();
		new CodeBlockDemo();
	}
}

12.final
只要满足以下条件就可以把一个类设计成final类:
① 某类不是专门为继承而设计。
② 出于安全考虑,类的实现细节不许改动。
③ 确信该类不会再被拓展。

class SuperClass
{
	final public void doWork()
	{
		System.out.println("父类方法");
	}
}
class SubClass extends SuperClass
{
	//public void doWork(){}   //报错,不能覆盖父类中的方法
	
}
class FinalDemo
{
	public static void main(String[] args) 
	{
		new SubClass().doWork();  //final 修饰方法可以被子类调用但是不能被覆盖
		System.out.println("Hello World!");
	}
}

13.单例设计模式

class ArraysUtil
{
	//在该类中,先自身先创建一个对象出来
	private static final ArraysUtil instance = new ArraysUtil();
	//私有化构造器
	private ArraysUtil()
	{

	}
	//向外暴露一个公共的静态方法用于获取自身的对象
	public static ArraysUtil getInsatance()
	{
		return instance;
	}
	public void sort()
	{
		System.out.println("排序操作");
	}
} 
class SingletonDemo 
{
	public static void main(String[] args) 
	{
		//ArraysUtil a = new ArraysUtil();
		ArraysUtil.getInsatance().sort();
	}
}

14.装箱和拆箱

public class IntegerDemo
{
	public static void main(String[] args)
	{
		//装箱操作:基本类型的值-->对应的包装类对象
		//int num1 =17 ;
		Integer num1 = new Integer(17); //方式1
		Integer num2 = Integer.valueOf(17);//方式2
		//拆箱操作:包装类对象---->转换为对应的基本类型变量
		int num3 =  num2.intValue();
		System.out.println(num1 +"," + num2+"," + num3);
		//自动装箱
		Integer num4 = 17;
		//自动拆箱
		int num5 = num4;

		Object obj = 17 ; //自装  Integer i=17 
				//引用自动类型转换,把子类对象赋给父类变量 Object obj = 1;
		
	}
}

15.abstract
使用abstract修饰且没有方法体的方法,称为抽象方法。
特点:
① 使用抽象abstract修饰,方法没有方法体,留给子类去实现。
② 抽象方法修饰符不能是private 和 final以及static,为什么?
③ 抽象方法必须定义在抽象类或接口中。
一般的:习惯性把abstract写在方法修饰符最前面,一看就知道是抽象方法。
抽象方法要求子类必须重新覆盖,若子类不覆盖,则子类也声明为抽象类.
使用abstract关键字修饰的类。
特点:
① 不能创建实例即不能new一个抽象类。
② 抽象类可以不包含抽象方法,若一旦包含,该类必须作为抽象类。
③ 若子类没有实现父类所有的抽象方法,那么子类也得作为抽象类(抽象派生类)。
④ 构造方法不能都定义成私有的,否则不能有子类(创建子类对象前先调用父类构造方法)。
⑤ 抽象类不能使用final修饰,因为必须有子类,抽象方法才能得以实现。
⑥ 是不完整的类,需作为基类,功能需要子类来实现。
一般的,抽象类命名,以Abstract作为前缀,见名知义.
抽象类可以包含普通方法.
抽象类和普通类的区别:
1):抽象类,也是一个类,可以定义抽象方法(没有方法体的方法).
2):抽象类不能创建对象.
除此之外,其他都一样.

abstract class Graph//抽象出图形类
{
	abstract public Double getArea();//没有方法体,留给子类实现 
}
class Circle extends Graph
{
	private Integer r ; //半径
	Circle(Integer r) //构造器
	{
		this.r = r;
	}
	public Double getArea() //求面积
	{
		return 3.14 * r * r;
	}
}
class Rectangle extends Graph
{
	private Integer width;//长
	private Integer height;//宽
	Rectangle(Integer width, Integer height)//构造器
	{
		this.width = width;
		this.height = height;
	}
	public Double getArea()
	{
		return width.doubleValue() * height.doubleValue();
	}
}
class Triangle extends Graph
{
	private Integer a;
	private Integer b;
	private Integer c;
	Triangle(Integer a, Integer b, Integer c)
	{
		this.a = a ;
		this.b = b;
		this.c = c;
	}
	public Double getArea() 
	{
		Double p = (a + b + c)/2.0;
		return Math.sqrt(p *(p - a ) * (p - b ) * (p - c ));
	}
}
class GraphDemo
{
	public static void main(String[] args)
	{
		//new Graph(); Graph是抽象类,无法实例化
		System.out.println(new Circle(10).getArea());
		System.out.println(new Rectangle(5,8).getArea());
		System.out.println(new Triangle(3,4,5).getArea());
	}
}

16.模版方法设计模式
模板方法模式(Template Method):在父类的一个方法中定义一个总体算法的骨架(模板方法),而将某一些步骤延迟到子类中,因为不同的子类实现细节不同。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

abstract class AbstractOperateTimeTemlate
{
	//模板方法:总体算法的骨架,子类不能去修改
	final public long getTotalTime()
	{
		long begin = System.currentTimeMillis();
		this.doWork();
		long end = System.currentTimeMillis();
		long time = end -begin;
		return time;
	}
	//具体的操作,需要子类来覆盖
		abstract void doWork();
	
}
class StringOperate extends AbstractOperateTimeTemlate
{
	public void doWork()
	{
		String str = " 1";
		for(int i = 0;i < 100000 ;i++)
		{
			str += i ;
		}
	}
}
class IntOperate extends AbstractOperateTimeTemlate
{
	public void doWork()
	{
		
		int sum = 0;
		for(int i = 0;i < 10000000 ;i++)
		{
			sum += i;
		}
		
	}
}
//模板方法设计模式
class TemplateMethod
{
	public static void main(String[] args)
	{
		System.out.println(new StringOperate().getTotalTime());
		System.out.println(new IntOperate().getTotalTime());
	}
}

17.接口
特点:

① 没有构造方法,不能实例化。

② 接口只能继承接口,不能继承类,且接口支持多继承。

 一个接口允许有多个父接口.
 interface IWalkable extends 接口1,接口2{}

③ 接口里的方法方法全是抽象的,默认修饰符是public abstract。

④ 接口里的字段全是全局静态常量,默认修饰符是public static final。

⑤ 接口里的内部类全是静态的,默认修饰符是public static。
接口的目的,在于高度的统一规范,接口必须要有实现才有意义.
我们把实现接口的类,称之为实现类,功能在于实现接口中的多个抽象方法.
实现类的语法:
public class 实现类 extends 父类 implements 接口1,接口2
实现类可以同时实现多个接口.
实现类实现接口之后,必须覆盖掉接口中所有的抽象方法,否则,该实现类只能作为抽象类.
实现类和接口之间的关系—>实现关系,是一种特殊的继承关系.
实现类覆盖接口中的方法,一般的称之为 实现
在这里插入图片描述
18.内部类
在开发中,一般的,什么时候使用内部类.
1):这个类只需要让当前的外部类访问.
2):匿名内部类.
四种内部类:

① 非静态内部类:内部类没有使用static修饰.
② 静态内部类: 内部类使用static修饰.
③ 局部内部类:在方法中定义的内部类,破坏封装,打死都不直接用.
④ 匿名内部类适合于仅使用一次使用的类
在这里插入图片描述
19.枚举
枚举特点:

① 枚举的直接父类java.lang.Enum,但是不能显示继承Enum。

② 枚举就相当于一个类,可以定义构造方法、成员变量、普通方法和抽象方法。

③ 默认私有的造方法,即使不写访问权限也是private。

④ 每个实例分别用一个全局常量表示,枚举类的对象是固定的,实例个数有限,不能使用new关键字。

⑤ 枚举实例必须位于枚举体中的最开始部分,枚举实例列表的后要有分号与其他成员相分隔。

⑥ 枚举实例后有花括号时,该实例是枚举类的匿名内部类对象(查看编译后的class文件)。
枚举的操作:
1):获取枚举类型所有的对象常量
Weekday[] days = Weekday.values();
2):把一个字符串转换为枚举的常量对象.
Weekday day = Weekday.valueOf(“THURSDAY”);
3):获取枚举的名称
在这里插入图片描述
简便写法
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37282683/article/details/88726640