面向对象
面向对象的程序设计(简称OOP)有三个基本特征:封装、继承和多态。
用面向对象的语言和面向对象的思想。
类和对象
类的声明
[类的修饰符] class 类名[extends 基类][implements 接口列表]{
类体
}[;]
//[]注明为可选
//类名:一般采用PascalCase命名规范
对象的创建
类是抽象的,要使用类定义功能,必须实例化类,即创建类的对象。
Person person = new Person();
//或
Person person;
person = new Person();
对象的使用
变量 = 对象名.成员变量
person.age = 18;
对象名.方法();
person.print();
对象的初始化方式
提供一系列的get 和 set 方法
package com.tulun.src;
class Person {
private int age;
private String name;
private String sex;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public void sleep() {//行为、方法 、函数
System.out.println("Person.sleep()");
}
public void eat() {
System.out.println("Person.eat()");
}
@Override //注解、重写
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
public class Demo5{
public static void main(String[] args) {
Person person = new Person();//实例化出来一个对象
person.setAge(10);
person.setName("zhangsan");
System.out.println(person.getAge());
}
}
通过合适的构造函数进行初始化
- 对象的创建分为两步:a.为对象分配内存 b.调用合适的构造函数
- 构造方法用于执行类的实例的初始化工作
- 构造方法的名称与类名相同
- 构造方法不能声明返回类型(也不能使用void),也不能返回值
class Person {
private int age;//数据
private String name;
private String sex;
//声明静态常量字段并赋初
private static final int COUNT = 10;//位于方法区
public Person() {//不带参数的构造函数,构造函数可以被重载
this("李四","man",66); //调用带有三个参数的构造函数
System.out.println("Person()");
this.age = 8; //this:指向当前对象的内存
this.sex = "man";
this.name = "王三";
}
public Person(String name,String sex,int age) { //带有三个参数的构造函数
System.out.println("Person(name,sex,age)");
this.age = age; //this:指向当前对象的内存
this.sex = sex;
this.name = name;
}
public Person(String name,String sex) { //带有两个参数的构造函数
this.sex = sex;
this.name = name;
}
- 方法的重载
- 每个类型成员都有唯一的签名
- 方法的签名由方法的名称及其参数的数目和类型组成
- 方法的签名不包含返回类型
- 只要方法的签名不同,就可以在一种类型内定义具有相同名称的多种方法,称作重载
静态初始化和实例初始化代
class Person {
private int age; //实例字段
private String name;
private String sex;
private static int count;//静态字段
{ //实例块初始化
this.name = "ss";
this.sex = "girl";
this.age = 8;
System.out.println("instance {} init");
}
public Person() { //构造方法
System.out.println("Person().constrcutor");
}
//静态初始化
static { //static所修饰的方法或者数据成员不依赖于对象
count = 10;
System.out.println("static {} init");
}
//静态方法
public static void sleep() {
System.out.println("static.sleep()");
}
//实例方法
public void eat() {
System.out.println("static.eat()");
}
- 静态方法不对特定实例进行操作,只能直接访问静态成员
- 在静态方法中使用this关键字会导致编译错误
- 静态方法通过类来访问
- 实例方法对某个给定的实例进行操作,能访问静态成员和实例成员
- 在调用实例方法的实例上,可以通过this显示地访问该实例
- 实例方法通过对象来访问
对象的初始化顺序:静态块初始化 (只初始化一次) —— 实例代码块初始化——构造函数初始化
class Person1{
static{
System.out.println("静态代码块初始化");
}
public Person1(){
System.out.println("构造函数初始化");
}
{
System.out.println("实例代码块初始化");
}
}
public class Test1 {
public static void main(String[] args) {
Person1 a = new Person1();
}
}
内部类
静态内部类
class OuterClass { //外部类
public int data1; //公共实例字段
private int data2; //私有实例字段
private static int data3; //私有静态实例字段
public OuterClass() {
System.out.println("OuterClass() init");
}
public void test1() { //公共实例方法
System.out.println("OuterClass().test1()");
}
//静态内部类
static class InnerClass {
public int data4;
OuterClass outr; //用于保存外部类的实例
public InnerClass(OuterClass outr) { //构造方法
this.outr = outr;
System.out.println("InnerClass()init");
}
public void test2() {
System.out.println(data4);
System.out.println(data3);
System.out.println(outr.data1);
System.out.println("InnerClass().test2()");
}
}
}
public class Demo5 {
public static void main(String[] args) {
//创建外部类的对象实例
OuterClass outerClass = new OuterClass();
//创建内部类的对象实例
OuterClass.InnerClass innerClass1 = new OuterClass.InnerClass(outerClass);
innerClass1.test2();
}
}
静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,必须通过外部类的实例去访问。
可以通过类名直接访问静态内部类的静态成员
实例内部类
实例内部类的成员方法可以访问其外部类的所有成员
class OuterClass2 {
public int data1;
private int data2;
private static int data3;
{
data1 = 999;
data2 = 888;
data3 = 777;
}
public OuterClass2() {
System.out.println("OuterClass() init");
}
public void test1() {
System.out.println("OuterClass().test1()");
}
class InnerClass2 {
private int data3 = 100;
public int data5 = 10;
//private static int date4 = 1000; error
private static final int DATA4 = 1000;
//实例内部类当中可以有静态数据成员但是只能是在编译期间确定的值即被final所修饰
//private static final int DATA4 = data5; error
public InnerClass2() {
System.out.println("InnerClass2().init");
}
public void test2() {
System.out.println(data1);//999
System.out.println(data2);//888 OuterClass2.this.
System.out.println(this.data3);//100
System.out.println(OuterClass2.data3);//777
//System.out.println(OuterClass2.this.data3); 警告
System.out.println("InnerClass2().test2()");
}
}
public static void main(String[] args) {
// InnerClass2 innerClass2 = new InnerClass2(); error
OuterClass2 outerClass2 = new OuterClass2();
//外部类名.内部类名 对象 = 外部类对象.new 内部类();
OuterClass2.InnerClass2 innerClass2 = outerClass2.new InnerClass2();
innerClass2.test2();
}
}
- 实例内部类是否拥有外部类对象?
- 拥有 ,因为有外部类的this引用对象。
- 实例内部类当中是否可以有静态数据成员?
- 可以有。但是只能是在编译期间确定的值即被final所修饰。
匿名内部类
匿名内部类没有显示的类名,在声明的同时,必须使用new关键字创建其对象实例。
匿名内部类一般用于比较简单,且仅在声明处使用一次的类
class OuterClass {
public void sayHello() {
System.out.println("hello");
}
}
public class Demo5 {
public static void test(OuterClass out1) {
out1.sayHello();
}
public static void main(String[] args) {
//第一种
new OuterClass() {
public void sayHello() {
System.out.println("main : hello");
}
}.sayHello();
//第二种
test(new OuterClass());
}
}
匿名内部类能不能访问方法的局部变量
public static void main(String[] args) {
int a = 10;
new Object(){
public void fun(){
int b = a;
}
};
}
//无输出
进栈 出栈
class Stack {
private int top;//栈顶指针
private int[] elem;
private int usedSize;
/*public Stack() {
this.top = 0;
this.elem = new int[10];
}*/
public Stack() {
this(10);
}
public Stack(int size) {
this.elem = new int[size];
}
//行为==》方法
public boolean isFull() {
if(this.top == this.elem.length) {
return true;
}
return false;
}
//进栈
public void push(int val) {
if(isFull()) { //判断栈是否满
return;
}
this.elem[top++] = val;//进栈——栈顶指针加一
this.usedSize++;
}
public boolean isEmpty() { //判断栈是否为空
return this.top == 0;
}
public void pop() { //出栈
if(isEmpty()) {
return;
}
this.top--; //出栈——栈顶指针减一
this.usedSize--;
}
public void show() {
for (int i = 0; i < this.top; i++) {
System.out.print(this.elem[i]+" ");
}
System.out.println(this.usedSize);
}
}
public class Demo5 {
public static void main(String[] args) {
Stack stack = new Stack();
stack.push(10);
stack.push(20);
stack.push(30);
stack.show();
stack.pop();
stack.show();
}
}