java面向对象
01-基本概念
定义:以基于对象的思维去分析解决问题,万物皆对象。
三大特性:封装,继承,多态;
02-类与对象
类与对象的关系
类是抽象的,对象是具体的。动物是类,老虎,大象是动物类的对象。
类的定义
类的关键字是class
类的名字要与文件名一样
public class Animal
{
String name; //动物都有名字属性
int age; //动物都有年龄属性
public void run() //动物都有跑的方法
{
System.out.println(name+"会跑");
}
}
类的创建和使用
public class Animal
{
String name; //动物都有名字属性
int age; //动物都有年龄属性
public void run() //动物都有跑的方法
{
System.out.println(name+"会跑");
}
public static void main (String[] args)
{
//定义一个动物类的猫
Animal cat;
//实例化cat
cat=new Animal();
//给对象赋值
cat.name="kitty";
cat.age=3;
cat.run();
}
}
内存分析
栈区存放cat对象
堆区存放cat对象的属性,name,age等
03-方法
方法的定义
public class Animal
{
//speak方法
public int speak(String name,int age,String ...colors) //String...为不定参数
{
System.out.println("我是"+name+"我今年"+age+"岁");
for(String color:colors) //foreach遍历形参colors
{
System.out.println(color);
}
int total=colors.length;
return total; //返回colors
}
public static void main(String[] args)
{
Animal cat=new Animal();
int n=cat.speak("kitty",3,"黄色","白色"); //n接收返回值
System.out.println(n);
}
}
方法的值传递和引用传递
public class Animal
{
int age;
public void speak(String name,Animal cat,int age,String...colors)
{
System.out.println("我是"+name+"我今年"+cat.age+"岁了");
for(String color:colors)
{
System.out.println(color);
}
cat.age=0;
age=4;
}
public static void main(String[] args)
{
Animal cat=new Animal();
int age=10;
cat.speak("kitty",cat,age,"black","orange");
System.out.println(cat.age); //传递的是cat对象的地址,所以在方法里修改会改变该内容
System.out.println(age); //传递的是值,在方法里修改不会改变内容
}
}
总结
- 传递的是值类型,在方法体内修改,不会改变值的内容。
- 传递的是引用类型(地址),在方法体内修改会改变内容。
04-方法的重载
定义:方法名称相同,但是参数的类型或者参数的个数不同。
返回值不同,但是传参相同会报错。
public class Add
{
int add(int a,int b)
{
System.out.println("add1");
return a+b;
}
int add(int a,int b,int c)
{
System.out.println("add2");
return a+b+c;
}
public static void main(String[] args)
{
Add test=new Animal();
test.add(1,2); //add1
test.add(1,2,3); //add2
}
}
05-static静态方法和普通方法
-
static方法:方法属于类本身
- 调用方式
- 类名.方法
- 对象.方法
- 调用方式
-
普通方法:属于类的对象
- 调用方式
- 对象.方法
- 调用方式
public class Animal
{
void fun1()
{
System.out.println("普通方法");
}
static void fun2()
{
System.out.println("静态方法");
}
public static void main(String[] args)
{
Animal test=new Animal();
test.fun1(); //普通方法属于对象,可以用对象来调用
Animal.fun2(); //静态方法属于类,用类来调用
}
}
静态方法常常用来定义工具类
06-递归方法
求n!
public class Animal
{
int fun1(int n)
{
return n>1?n*fun1(n-1):1; //递归
}
public static void main(String[] args)
{
Animal test=new Animal();
System.out.println(test.fun1(4));
}
}
07-构造方法和this关键字
构造方法:是一个特殊的方法,这个特殊方法用于创建实例时执行初始化。
假如没有构造方法,系统会自动生成一个默认的无参构造方法,假如有构造方法,系统不会自动生成构造方法。
public class Animal
{
private String name; //private 私有的,只能内部访问,作用域是类的内部
private int age;
//外部默认访问string为null,int为0
void speak()
{
System.out.println("我叫"+name+"我的年龄是"+age);
}
Animal()
{
System.out.println("无参的构造方法");
}
Animal(String name1,int age1)
{
this.name=name1;
this.age=age1;
System.out.println("有参的构造方法");
}
public static void main(String[] args)
{
Animal test=new Animal("kitty",10);
test.speak();
// Animal test=new Animal();我叫null,我的年龄是0 无参的构造方法
// Animal test=new Animal("kitty",10);我叫KITTY,我的年龄是10 有参的构造方法
//注意!注释一中返回null和0是因为没有定义。入口函数是在animal类里面的,可以访问 private的name和age。
//如果将无参的构造方法注释掉然后Animal test=new Animal();会报错,因为有了构造方法系统就不会自动生成构造方法。
}
}
this
this表示当前对象
this可以调用本类中的属性
this可以调用构造方法
注意,构造方法也有访问权限
public class Animal
{
private String name;
private int age;
Animal()
{
System.out.println("无参的构造方法");
}
Animal(String name1,int age1)
{
this(); //== Animal()
this.name=name1;
this.age=age1;
System.out.println("有参的构造方法");
}
}
08-访问权限以及package import关键字
private(私有) | package(包访问权限) | protected(子类访问权限) | public(公共访问权限) | |
---|---|---|---|---|
同一个类中 | 1 | 1 | 1 | 1 |
同一个包中 | 1 | 1 | 1 | |
子类中 | 1 | 1 | ||
全局 | 1 |
private利用get和set方法设置外界接口
//animal类
public class Animal
{
private int a;
public int getA()
{
return a;
}
public void setA(int a)
{
this.a=a;
}
}
//外界访问animal类
public class demon
{
public static void main (String[] args)
{
Animal cat=new Animal();
//利用get和set方法来访问设置外部类中的private类型的属性
cat.setA(3);
cat.getA();
}
package
包定义,相同的类放在包里面
import
用来导入类
package 包名 //包定义
import 包名.类名 //导入类
public class animal
{
public static void main(String[] args)
{
//使用别的包中的类要用import来导入类
//使用同一个包中的类不需要导入
类名 test=new 类名();
}
}
09-内部类
定义:在类的内部定义类
内部类优点:可以方便的使用外部类的属性
内部类缺点:破坏类的基本结构
慎用内部类
public class Animal
{
private int a=1;
public class inner
{
//在内部类定义一个show方法
public void show()
{
//内部类可以直接使用外部类的属性和方法
System.out.println(a);
}
}
//在外部类定义一个show方法
public void show1()
{
inner out=new inner();
out.show();
}
public static void main(String[] args)
{
Animal out2=new Animal();
out2.show1();
}
}
如何在外部直接调用内部类
Outer outer1=new Outer();
Outer.Inner inner1=outer1.new Inner();
10-代码块
普通代码块
public class Animal
{
public static void main(String[] args)
{
int a=1;
//普通代码块
{
a=2;
System.out.println("普通代码块");
}
System.out.println(a); //2
}
}
构造块
构造块在构造方法之前执行的,作用是补充构造方法
如果你有两三个构造方法都需要要执行相同的初始化操作,那么可以用到构造块
//不论执行哪个构造方法都会执行通用构造块里的内容
public class Animal
{
{
System.out.println("通用构造块");
}
public Animal()
{
System.out.println("构造方法1");
}
public Animal(int a)
{
System.out.println("构造方法2");
}
public static void main(String[] args)
{
}
}
静态代码块
public class Animal
{
{
System.out.println("通用构造块");
}
static{
System.out.println("静态代码块");
}
public Animal()
{
System.out.println("构造方法1");
}
public Animal(int a)
{
System.out.println("构造方法2");
}
public static void main(String[] args)
{
}
}
静态代码块只执行一次!
执行顺序是
- 静态代码块
- 通用构造块
- 构造方法一
- 通用构造块
- 构造方法二
11-String类
实例化String类
方法一
- String name1=“张三”;
- 直接赋值的方式,创建的对象存放在字符串对象池中,假如存在就不会再创建。
- String name1=“aaa”;
- String name2=“aaa”;
- 第二条语句发现已经创建了相同的内容那么就不会重新创建,name1和name2都指向同一个内容
- 直接赋值的方式,创建的对象存放在字符串对象池中,假如存在就不会再创建。
方法二
- String name2=new String(“李四”);
- new对象的方式,每次都创建一个新对象
==和equals方法
-
==比较的是引用(地址),不是内容
- 使用方法:name1==name2
-
equals比较的是内容
- 使用方法:name1.equals(name2)
他们的返回值都是布尔类型
字符串内容不可变性
字符串的特性:不能改变字符串的内容,只能通过指向一个新的内存地址。
//改变string的内容
String name=“张”;
//变为张三
String name+=“三”;
本来指向“张”,之后指向“张三”;
String类使用
- char charAt(int index) 返回指定索引处的char值
- int length() 返回此字符串长度
- int indexOf() 返回指定字符串在此字符串中第一次出现的索引
- String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子串。该子字符串从指定索引处的字符开始,直到此字符串末尾。
- String toUpperCase() 使用默认语言环境的规则将此string中的所有字符替换为大写。
12-继承
继承的定义:子类能够继承父类的属性和方法;
注意点:Java中只支持单继承(只能继承一个父类),私有方法不能继承;
public class Animal
{
private String name;
private int age;
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return this.name;
}
public void setAge(int age)
{
this.age=age;
}
public int getAge()
{
return this.age;
}
public void say()
{
System.out.println("我是动物,我叫:"+this.name+",我的年龄是"+this.age);
}
}
//继承使用extends关键字
public class Dog extends Animal
{
public static void main (String[] args)
{
Dog dog=new Dog();
dog.setAge(1);
dog.setName("qqq");
dog.say();
}
}
父类的方法也可以重写,截取上述代码片段
public class Dog extends Animal
{
//子类的实例对象调用say方法时,优先调用重写的构造方法
public void say()
{
System.out.println("我是一只狗,我叫:"+this.name+",我的年龄是"+this.age);
}
}
super
使用super关键字来代表父类
public class parent
{
private int age;
public void say()
{
System.out.println("父类的say方法");
}
public parent()
{
System.out.println("父类无参构造方法");
}
public parent(int age)
{
this.age=age;
System.out.println("父类有参构造方法")
}
}
public children extends parent
{
private String name;
public children()
{
super();
System.out.println("子类无参构造方法");
}
public children(String name,int age)
{
super(age);
this.name=name;
System.out.println("子类有参构造方法");
}
public static void main(String[] args)
{
children c1=new children("小明",10)
super.say();
//结果:父类有参构造方法
//子类有参构造方法
//父类的say方法
}
}
13-final关键字
- 使用final声明的类不能被继承
- 使用final声明的方法不能被重写
- 使用final声明的变量不能被修改,即为常量
//test类将不会被继承
public final class test
{
//action方法将不会被重写
public final void action()
{
}
//a变量不能被修改
private final int a=1;
}
14-抽象类
抽象类的定义:在Java中含有抽象方法的类称为抽象类,不能生成对象。
抽象类是部分方法不实现,部分方法可以实现。
-
包含一个抽象方法的类是抽象类
-
抽象类和抽象方法都要用abstract关键字声明
-
抽象方法只需要声明而不需要实现
-
子类必须重写抽象类中的全部抽象方法才能继承抽象类
-
抽象类不能被实例化
-
抽象类中可以不包含抽象方法,且抽象类中可以包含普通方法。
//抽象类的定义
public abstract class people
{
private int age;
public void setAge(int age)
{
this.age=new age;
}
public int getAge()
{
return this.age;
}
//定义抽象方法,抽象方法不需要写具体内容
public void abstract say();
}
//子类继承抽象类
public children extends people
{
//必须重写父类抽象方法!!!!
public void say()
{
System.out.println("重写父类的抽象方法")
}
}
15-接口
接口的定义:是一种特殊的“抽象类”,没有普通方法,由全局常量和公共抽象方法所组成。
//定义一个接口A
public interface A
{
//定义全局常量
public static final String title="全局常量";
//定义抽象方法(接口中的方法都是抽象方法,abstract可以省略)
public abstract void say();
}
实现接口
//实现接口,用implements关键字
public class test implements A
{
public void say()
{
System.out.println("重写接口的抽象方法");
}
public static void main (String[] args)
{
test t=new test();
t.say();
System.out.println(test.title);
}
}
实现多个接口
注意,继承只能单继承,但是接口可以实现多个!
//test类继承接口A,B
public class test implements A,B
{
}
实现接口和继承类
//必须先继承再实现接口
public class test extends C implements A,B
{
//test类继承父类C,实现接口A,B
}
接口的继承
接口可以实现多继承!
//接口D继承接口A,B
public interface D extends A,B
{
}
16-对象的多态性
Java中多态性的体现
- 方法的重载和重写
- 可以用父类的引用指向子类的具体实现,而且可以随时更换为其他子类的具体实现
//父类
public class Animal
{
public void say()
{
System.out.println("我是一只动物!");
}
}
//子类cat
public class Cat extends Animal
{
public void say()
{
System.out.println("我是一只猫!");
}
}
//子类Dog
public class Dog extends Animal
{
public void say()
{
System.out.println("我是一只狗!");
}
}
//测试类
public class test
{
public static void main(String[] args)
{
/*Cat cat=new Cat();
cat.say();*/
//可以用父类的引用指向子类的具体实现
Animal animal=new Cat();
animal.say();
//更换子类的其他实现
animal =new Dog();
animal.say();
//结果
//我是一只猫!
//我是一只狗!
}
}
对象的转型
- 向上转型:子类对象->父类对象 安全
Animal animal=new Cat();
- 向下转型:父类对象->子类对象 不安全
Animal animal=new Cat();
//向下转型
Dog dog=(Dog) animal;
//第二次向下转型的时候会报错
Cat cat=(Cat) animal; //报错!!!
接口和类实现向上转型和向下转型的写法都是一样的!
17-Object类
Object类是所有类的父类!
定义一个类默认是继承object类的!
public class A
{
public A()
{
super(); //这里super指向的是Object类
}
}
object类常用方法
-
public String toString()
-
返回该对象的字符串表示
Test t1=new Test();
System.put.println(t1);
//打印t1默认调用toString()方法
//上面的可以这样写
System.put.println(t1.toString());
-
可以改写toString()方法,使得打印的时候打印出自己想要的东西
-
打印对象默认调用 对象.toString()方法
-
-
piblic boolean equals(Object obj)
- 指示其他某个对象是否与此对象“相等”
用法
p1.equals(p2)
只有内存地址一样才返回true
18-instanceof关键字
作用:判断一个对象是否属于一个类
格式:对象instanceof 类 返回的是布尔类型
向下转型做判断
19-匿名内部类
作用:假如某个类只使用一次,则可以使用匿名内部类。
//接口A
public interface A
{
public void a();
}
//B实现接口A
public class B impelements A
{
public void a()
{
System.out.println("只实现一次的方法")
}
}
//测试类
public class test
{
public void test(A a)
{
a.say();
}
publis static void main(String[] args)
{
test t=new test();
t.test(new B());
//结果:只实现一次的方法
//有时候没必要定义B类,所依可以这样写(匿名内部类)
t.test(new A())
{
public void say()
{
System.out.println("重写接口的say方法,一次性使用")
}
}
}
}
20-包装类
每个基本类型都有一个对应的类
基本类型 | 包装类型 |
---|---|
int | Interger |
char | Character |
short | Short |
long | Long |
iloat | Float |
double | Double |
boolean | Boolean |
byte | Byte |
装箱和拆箱
- 装箱:将基本变量变成对象变量
- 拆箱:将变量对象变为基本变量
public class Test
{
publis static void main(String[] args)
{
int a=1;
Integer i=new Integer(a); //装箱
int b=intValue(); //拆箱
}
}
自动装箱和拆箱
public class Test
{
publis static void main(String[] args)
{
Integer i=1; //自动装箱
int a=i; //自动拆箱
}
}
包装类的作用
用户输入两个字符串a,b,计算a+b的值
public class Test
{
publis static void main(String[] args)
{
String a="1";
String b="2";
int m=Integer.parseInt(a);
int n=Integer.parseInt(b);
System.out.println(m+n);
}
}
21-设计模式
单例模式
在Java应用中,单例对象能保证在一个JVM(虚拟机)中,该对象只有一个实例存在。
饿汉式单例实现(提前实例化)
public class Single
{
//私有的构造方法
private Single()
{
}
//饿汉式单例实现
private static final Single single1=new Single();
//静态工厂方式
public static Single getInstance()
{
retuin single1;
}
}
//测试类
public class Test
{
publis static void main(String[] args)
{
//不论新建多少个对象都是指向同一个堆区
Single single1=Single.getInstance();
}
}
懒汉式单例实现(在第一次调用的时候实例化)
public class Single
{
//私有的构造方法
private Single()
{
}
//懒汉式单例实现
private static Single single2;
//静态工厂
public static Single getInstance()
{
//第一次调用的时候实例化,只会实例化一次
if(single2==null)
{
single2=new Single();
}
return single2;
}
}
//测试类
public class Test
{
publis static void main(String[] args)
{
Single single2=Single.getInstance();
}
}