面向对象 以类的方式组织代码 以对象形式的组织封装数据
面向对象三大特征 封装 继承 多态
先有对象后有类 对象是具体的事物 是对抽象概念的具体实例 类是抽象的 是对对象的抽象
创建一个对象 有static关键字的是从属于类而非对象的静态方法
无static关键字的方法是需要类实例化之后才存在
public class Student { //和类一起加载的 public static void sayHello(){ System.out.println("Hello"); } //类实例化之后才存在 public void sayHi(){ System.out.println("hi"); } }
分别调用这两个方法
//调用静态方法 类名.方法名 Student.sayHello(); //调用成员方法 Student student = new Student(); student.sayHi();
java中的值传递和引用传递 请看下面的两个方法
public static void change(Person p){ p.name = "abc"; } public static void change(String s){ s = "abc"; }
调用这两个方法 第一种就是值传递 不会改变s的内容
第二种引用传递 传递的是对象的引用(指针)会改变内容
String s = "aaa"; change(s); System.out.println(s); //aaa Person p1 = new Person(); change(p1); //引用传递 System.out.println(p1.name); //abc
构造器(构造方法) 创建对象的时候会调用
如果不写也会存在构造方法(默认无参构造器)
写了有参构造器 无参构造器就没了 不过通常要写无参构造器
构造方法名字必须和类名相同 且没有返回值
其作用是实例化一些对象
idea中alt+insert可以自动生成构造器
this关键字就是代指这个类 谁调用这个类 this就是谁
程序要追求高内聚 低耦合
public class Student { String name; int age; public Student(){ } public Student(String name , int age){ this.name = name; this.age = age; } public void study(){ System.out.println(this.name + " is study"); } }
在main方法中测试
Student student = new Student(); student.name = "Jack"; student.study(); Student student2 = new Student("Bob", 24); System.out.println(student2.name + " " + student2.age);
通俗点说 就是把数据封装起来 对外提供一个接口
提高程序的安全性 隐藏代码细节 统一了接口 提高了系统的可维护性
简单来说 属性私有 提供set get
请看下面的代码 private关键字 使得属性和方法只能在本类中调用 别的类中访问不到
class Student{ //属性私有 get set private String name; private int age; //提供public get set 方法 public String getName(){ return this.name; } public void setName(String name){ this.name = name; } }
调用setter和getter方法
public static void main(String[] args) { Student student = new Student(); student.setName("Jerry"); System.out.println(student.getName()); }
继承的本质是对类的抽象 实现对现实世界更好的建模
子类继承父类 就会拥有父类的全部不私有的方法和属性
而使用private关键字的属性和方法不会被继承
通过final修饰的类不能被继承
适用范围 public protected default private
在java中所有的类都继承object类
java中只能单继承 一个子类只能有一个父类
请看下面的代码 子类中没有say()方法 但是继承(extends关键字)后可以调用父类的方法
public class Test01 { public static void main(String[] args) { Student student = new Student(); student.say(); //hello } } class Person{ public void say(){ System.out.println("hello"); } } class Student extends Person{ //子类是父类的拓展 }
用super关键字可以访问父类的属性和方法
public class Test01 { public static void main(String[] args) { Student student = new Student(); student.test(); // Teemo Teemo jack student.test2(); //test hello } } class Person{ protected String name = "jack"; public void say(){ System.out.println("hello"); } } class Student extends Person{ //子类是父类的拓展 private String name = "Teemo"; public void test(){ System.out.println(name); System.out.println(this.name); System.out.println(super.name); } public void say(){ System.out.println("test"); } public void test2(){ say(); super.say(); } }
子类继承父类之后 创建对象的时候会默认调用父类的无参构造器
原因是子类无参构造第一样隐藏了一个super();这个方法会调用父类的无参构造
这句话只能放在第一行 也可以super(xxx);里面放上参数(父类的有参构造器)
当然可以用this();代替(调用子类的无参构造)当然也只能放在构造器的第一行
public Student(){ super("jack"); }
关于方法重写 当在子类写出一个方法方法名 返回值 形参类型一致时 (修饰符范围可以扩大 抛出的异常可以被缩小但不能被扩大) (对final修饰的不能重写)子类调用这个方法 会优先调用子类的这个写出来的方法 请看下面的代码
public class Test01 { public static void main(String[] args) { B b = new B();//方法重写 b.test1(); //B test1 } } class A{ public void test1(){ System.out.println("A test1"); } } class B extends A{ public void test1(){ System.out.println("B test1"); } }
多态可以使我们能够动态编译 可拓展性更强 能让程序变的更灵活
多态是方法的多态 属性没有多态
父类和子类必须有关系
个人理解 s2调用方法的时候 现在父类里面找到那个方法 找不到就不能调用(比如test2()方法)找到之后检查子类是否重写了 如果重写了就调用重写之后的方法
s1则是直接在子类中找这个方法 找不到再去父类中找 也是调用的重写之后的
public class Test01 { public static void main(String[] args) { Student s1 = new Student(); //父类的引用指向子类 Person s2 = new Student(); Object s3 = new Student(); //子类重写了父类的方法 就调用子类的 s2.test1(); //Student test2 //没有重写就调用父类的方法 s2.test3(); //Person test3 } } class Person{ public void test1(){ System.out.println("Person test1"); } public void test3(){ System.out.println("Person test3"); } } class Student extends Person{ public void test1(){ System.out.println("Student test2"); } public void test2(){ System.out.println("Student test2 "); } }
请看下面的代码 父类型引用指向子类型对象 上来寻找的是左边的那个类
public class Test01 { public static void main(String[] args) { A a = new B(); B b = new B();//方法重写 a.test1(); //B test1 b.test1(); //B test1 //static方法从属于类 a.test2(); //static A b.test2(); //static B } } class A{ public void test1(){ System.out.println("A test1"); } public static void test2(){ System.out.println("static A"); } } class B extends A{ public void test1(){ System.out.println("B test1"); } public static void test2(){ System.out.println("static B"); } }
关于instanceof关键字
能否编译通过就是创建对象所在的类与instanceof后面的是否有继承关系
而true和false是由对象右边的具体实例与instanceof后面能否互相转化
public class Test01 { public static void main(String[] args) { //能否编译通过就是创建对象所在的类与instanceof后面的是否有继承关系 //而true和false是由对象右边的具体实例与instanceof后面能否互相转化 Person s1 = new Student(); System.out.println(s1 instanceof Student); //true System.out.println(s1 instanceof Person); //true System.out.println(s1 instanceof Teacher); //false Student s2 = new Student(); System.out.println(s2 instanceof Student); //true System.out.println(s2 instanceof Person); //true ((Student)s1).go(); //强制类型转化 } } class Person{ } class Student extends Person{ public void go(){ System.out.println("go"); } } class Teacher extends Person{ }
static关键字 记住在方法区存在 且从属于类 请看下面的代码
public class Test02 { static int i = 0; { //代码块(匿名代码块) System.out.println("匿名代码块"); } static { //静态代码块 //类加载的时候执行 只执行一次 System.out.println("静态代码块"); } public Test02(){ System.out.println("构造器"); } public static void main(String[] args) { Test02 t = new Test02(); /* 静态代码块 匿名代码块 构造器 */ test(); test(); System.out.println(i); //2 } public static void test(){ i++; } }
抽象类用abstract修饰
抽象方法只有方法的名字 没有方法的实现
抽象类可以有普通的方法
类中有抽象方法必须是抽象类
继承抽象类必须要实现它其中所有的抽象方法 除非自己本身是抽象的
public abstract class Action { public abstract void doSome(); } class A extends Action{ @Override public void doSome() { System.out.println("doSome"); } }
接口就是规范 定义的是一组规则
接口中的方法都是抽象的 public abstract
类可以利用接口实现多继承(伪多继承)
实现类必须实现接口定义的所有方法
请看代码
public interface UserService { void add(String name); int query(int num); }
public class UserServiceImpl implements UserService { @Override public void add(String name) { System.out.println("add"); } @Override public int query(int num) { System.out.println("query"); return -1; } }
public class Outer { private int id; public void out(){ System.out.println("out"); } class Inner{ //可以获得外部类私有属性 私有方法 public void in(){ id = 10; System.out.println(id); System.out.println("in"); } } }
public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); inner.in(); // 10 in }
加入static关键字就变成静态内部类 由于程序开始时静态内部类就创建了 故访问不到id
匿名内部类 没有名字的类
public class Test02{ public static void main(String[] args) { UserService user = new UserService() { public void hello() { System.out.println("Hello"); } }; } } interface UserService{ void hello(); }