面向对象
宏观上是通过分类的思维模式,进行分类,然后堆分类的问题单独思考。
思想: 抽象!!
Object-oriented Programming OOP
以类的方式组织代码,以对象的组织封装数据
封装,继承,多态
1. 静态,非静态方法
class Student(){
public static void a(){
}
public static void b(){
}
}
// a 是 static, b 是 static
// a() 中可以 调用 b(), 两者都是在类创建的时候就存在了
// a 是 static , b 不是,
// a() 中不可以调用b(),因为b()在实例化的时候才存在,而a已经存在了
// a 不是 static, b 不是 static
//a() 中可以调用 b(), 俩这都在实例化的时候同时存在。
值传递和引用传递:
把 a= 1;传入函数,传入的是a的值,而不是a这个变量名,
把 person.name传入函数,传入的是这个变量的引用名,,引用传递。
2. 创建与初始化对象
使用new创建时,除了分配内存空间,对创建对象默认初始化,还有对类中的构造器进行调用。
构造方法的特点: 必须和类的名字相同,必须没有返回值也不写void
IDEA中查看已经预编译的class文件:
打开structure, module, 在add 目录下面导入out文件夹,就可以看到编译的class文件
定义了有参构造之后,想无参构造(返回null)必须写一遍无参构造的方法。(构造器可以重载的)
快捷键:直接生成有参,无参构造:Alt + Insert
,
3. 内存分析
4. 封装
属性私有,get/set
- 提高安全性,保护数据
- 隐藏代码的实现细节(在get,set里面可以加判断)
- 统一接口访问
- 系统可维护增加
快捷键: Alt + Insert ,可以generate get() and set()
public class Student{
//属性私有
private String name;
private int id;
private char sex;
//get set 方法用于操作私有属性
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
}
5. 继承 extends
object, super, 重写 三块
1. object
快捷键:查看继承树: Ctrl + H
四种修饰符
public, protected, default, private
Student 要继承Person的属性,
- Person的属性时public
- Person的属性时private, 但提供方法可以访问(get, set)
Java中所有的class 都隐式的继承object类。
父类的private方法和属性不能被继承!!!
私有属性不能被继承
class Student extends Person{
this.name; //调用自己的name
super.name;//调用父类的name
}
2. super
调用this() 自己的构造器,也必须放在第一行(不能同时调用super构造和this构造)
public class Person{
public Person(){
}
}
//another file
public class Student extends Person{
public Student(){
super();//子类调用父类的构造器是隐藏的,如果要显式构造,则必须放置在第一句!!!
}
}
3. 重写方法
快捷键: Alt + Insert , @override
- 有static, b对象调用的是B类的方法,所以输出和左边定义的数据类型有关。
class B{
public static void test(){//注意都是static方法
sout("B");
}
}
class A extends B{
public static void test(){
sout("A");
}
}
class Application{
psvm{
A a = new A();
a.test();
B b = new A();//重点:父类的引用指向了子类
b.test();
}
}
>>输出结果a.test()为A, b.test() 为B
- 没有static, 重写方法, b对象调用的是new A()时候的对象方法,所以输出为new A()的对象方法。
class B{
public void test(){
sout("B");
}
}
class A extends B{
@Override
public void test(){
sout("A");
}
public void test2(){
sout("just A not B");
}
}
class Application{
psvm{
A a = new A();
a.test();
B b = new A();//重点:父类的引用 指向了 子类
b.test();
}
}
>>输出结果a.test()为A, b.test() 为A
b.test2()//无法访问,因为b还是B类型的对象。
- 总结:一个对象的实际类型是确定的
b在创建时,虽然new A(), 但A是继承B的,b向上转型为B(), 但使用new A()时的对象方法。而如果是父类B()中没有的方法如test2(),则b无法访问。
6. 多态
多态:父类的引用可以指向子类的实现
Student s1 = new Student();//一个对象的实际类型是确定的
Person s2 = new Student();//可以指向的引用类型就不确定了,引用类型是指左边的变量,父类的引用可以指向子类变量
如.5总结:
s1 是Student类,能调用的方法是自己的,或者继承的方法。
s2 是Person类,可以指向子类,但不能调用子类独有的方法。
对象能指向那些方法,主要看左边的对象类型,和右边关系不大。
多态是方法的多态,属性没有多态
7. instanceof关键字 类型转换
- 用来判断一个类是不是另一个类
sout(s1 instanceof Person);//返回True
-
强制转化(向下转型)
和基本类型强制转化一样,从高转低需要强制转换,低转高不需要(8字节转4字节需强制,4字节转8字节直接转)
Person s1 = new Student();//低转高不需要强制转换 Student s2 new Student(); /* Person : run() Student: run(), go() */ s1.go();//不可以执行,需要把s1强制转换为student类才可以用go方法。 ((Student) s1).go();//可与执行
子类转父类:(向上转型)
Person person = s2;//子类转父类会丢失方法(类似于精度问题)
8. Static 总结
-
已经会了
-
静态代码块,在类加载的时候执行,
public class Student{ { sout("匿名代码块");//在第二次加载类的时候也执行 } static { sout("静态代码块");//这个是最先执行的,并且只执行一次 } public Student(){ sout("构造方法"); } } >>(顺序) 静态代码块,匿名代码块, 构造方法
-
final修饰的类,不能被继承,相当于被断了。
9. 抽象类
public abstract class Person{
public abstract run();
}
不能new抽象类,只能靠子类实现,对子类约束
抽象方法必须在抽象类中
10. 接口(只有规范)
接口就是规范,定义的是一组规则。精髓? interface
public interface interfacename{
//返回值类型 方法名称(参数)
void run(String name);//方法前面的 public abstract 可以省略
//只能写public abstract方法
}
public class xxxImpl implements interfacename{
//具体实现,重写接口方法
@Override
}
11. 内部类
一个java文件只能有一个public class, 但可以有多个class
- 内部类
public class Outer {
private int id =10;
public void out(){
System.out.println("outer method");
}
class Inner{//定义内部类
public void in(){
System.out.println("inner method");
}
public void getID(){//内部类可以访问外部类的数据和方法
System.out.println(id);
}
}
}
//another files
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();//内部类的定义
inner.in();
}
-
静态内部类
内部类的定义为 class static Inner{}, 不能访问id值,因为id在创建类的时候不存在,
-
局部内部类
public class Outer{ public void method(){ class Inner{//方法里的类 } } }
-
匿名类
class Apple{} //使用: new Apple().eat();//直接调用类的方法