1类和对象
面向过程:强调的是功能行为
面向对象:将功能封装进对象,强调具备了功能的对象。先要去找具有所需的功能的对象来用。 如果该对象不存在,那么创建一个具有所需功能的对象。
面向对象的特征: 封装(encapsulation) 继承(inheritance) 多态(polymorphism)
非静态成员变量随着对象的建立而建立,存在于对象所在的堆内存中。
对象内存结构:
Car c1 = new Car();
一句代码开辟两块存储区,一个是给对象c1,一个是给对象实体Car。c1在栈内存中指向new出来的对象堆内存,对象堆内存中存放成员堆内存。
栈中指向存放堆内存的指针,真正的内存在堆中。只有new才开辟堆内存空间,仅声明对象不new,栈中存放一个默认值null,它也占空间。引用和指针一个概念。
四种对象初始化方法:
import java.util.Date;
import java.text. SimpleDateFormat;
public class test {
private int age = 18;
public int num;
static//不能访问没有初始化的成员和非静态成员
{
age = 21;
System.out.println("静态构造代码块");
}
{
age = 20;
System.out.println("构造代码块");
}
public test(int age)
{
this.age = age;
System.out.println("构造函数");
}
public void getage()
{
System.out.println(age);
}
public static void main(String args[]) {
test t = new test(20);
//test t = null;
t.getage();
System.out.println(t.num);
}
}
运行结果:
静态构造代码块
构造代码块
构造函数
20
0
运行顺序:默认值初始化(数值型:0,引用型:null),声明对象时赋初值,静态构造代码块(每个类只执行一次),构造代码块,构造函数
当类对象为null时不执行构造代码块,静态构造会执行。因为构造代码块非静态是跟随对象的创建而执行,静态构造跟随类的加载而执行。构造函数可以访问没有初始化的成员变量,静态代码块不能访问没有初始化的成员变量。
import java.util.Date;
import java.text. SimpleDateFormat;
public class test {
private static int age = 18;
static
{
System.out.println("默认值"+age);
age = 21;
System.out.println("静态构造代码块"+age);
}
public static void main(String args[]) {
test t = null;
}
}
运行结果:
默认值18
静态构造代码块21
构造代码块和构造函数的区别: 构造代码块是给所有对象进行统一初始化, 而构造函数是给对应的对象初始化。构造代码块中定义的是不同对象共性的初始化内容。
静态成员变量与成员变量的区别:静态成员变量单独划分一块存储空间,不与具体的对象堆空间绑定在一起,该存储空间被所有对象共享(计数器),即在声明多个对象时不进行拷贝,只占用一块内存。static不能修饰构造函数内部的变量,静态方法中不能有this和super。
final:final变量只能赋值一次,final方法可以被继承但不能重写,final类中的方法都是final方法。
this:this(null/*)在构造函数中调用其他构造函数,只能在第一行。
单例设计模式:
1)构造函数私有化
2)类中提供一个本类对象
3)提供一个方法获取该对象
class Single//饿汉式
{
private Single(){}
private static Single s = new Single();
public static Single getInstance()
{
return s;
}
}
包:
classpath变量值的最后有分号与无分号的区别:是否在当前目录下找类或包。
不同包之间的访问(包括继承):类必须是pubilc,类中成员必须是public或者protected
2继承
成员变量同名不会被覆盖,用this和super进行访问;成员方法同名会出现覆盖,覆盖的子类方法反问权限要大于等于父类方法,静态只能覆盖静态
内部类只能访问被final修饰的局部变量
(50条消息) 为什么局部内部类和匿名内部类只能访问final的局部变量?_云川之下的博客-CSDN博客
多态的体现:父类或者接口的引用指向或者接收自己的子类对象。
Animal 类是Cat的父类
Animal a = new Cat();//类型提升。 向上转型。
Cat c = (Cat)a;//向下转型。
抽象类的特点:
抽象类和抽象方法必须用abstract关键字修饰;
抽象方法只有方法声明,没有方法体;
抽象类不能被实例化,及不可以用new创建对象;
抽象类通过子类实例化,子类需要覆盖(实现)抽象类中所有的抽象方法才可以创建对象,否则该子类也是抽象类。
abstract不能和final、static、private共存
3接口:interface
成员常量 public static final
成员函数 public abstract
接口的特点:
接口是对外暴露的规则;
接口是程序的功能扩展;
接口可以用来多实现;
类和接口之间是实现关系,而且类可以继承一个类,同时实现多个接口;
接口和接口之间可以有多继承关系。
类和类之间只能单继承,不能多继承。 接口和接口之间可以多重继承。 类可以实现多个接口。既有继承又有实现时,应该先继承后实现。
内部类:
内部类可以直接访问外部类中的成员,包括私有成员。 而外部类要访问内部类中的成员必须要建立内部类的对象。
class Outer
{
private int x = 3;
class Inner//内部类
{
int x = 4;
void function()
{
int x = 6; //如何访问不同作用域的x
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();
}
}
4异常:
Exception和Error的子类名都是以父类名作为后缀
getMessage() 获取异常信息,返回字符串。
toString() 获取异常类名和异常信息,返回字符串。
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。 printStackTrace(PrintStream s) 通常用该方法将异常内容保存在日志文件中,以便查阅。
throws用于标识函数暴露出的异常。
throw用于抛出异常对象。
throws与throw的区别: thorws用在函数上,后面跟异常类名。 throw用在函数内,后面跟异常对象。
一个try块可以有多条catch语句
catch、finally都不能单独使用,必须始终与try块在一起
try块存在,catch和finally块至少存在一个。
finally代码块只有一种情况不会被执行。就是在之前执行了System.exit(0)。即一般情况下finally必执行。
自定义异常:
Class DemoException extends Exception
{
DemoException(String message)
{
super(message);
}
}
通过throw将自定义异常抛出。