Java入门之面向对象
1、Java的核心思想是OOP(Object-Oriented Programming)
本质上就是,以类的方式组织代码,以对象的组织封装数据。
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
从代码运行角度考虑是先有类后有对象。类是对象的模板。
2、三大特性
- 封装:高内聚,低耦合;属性私有,通过get()/set()方法来获取和赋值
- 继承:通过extends关键字来表示子类继承父类,只能是单继承。
- 多态:同一方法可以根据发送对象的不同类型而采用多种不同的行为方式;一个对象的实际类型是确定的,但可以指向对象的引用类型有很多。
1 public class Pet { 2 public void run(){ 3 System.out.println("Pet run"); 4 } 5 }
1 public class Dog extends Pet{ 2 private String name; //属性私有 3 //Alt+Insert来生成get/set方法 供外面的类进行访问 4 public String getName() { 5 return name; 6 } 7 8 public void setName(String name) { 9 this.name = name; 10 } 11 12 @Override 13 public void run() { 14 System.out.println("Dog run"); 15 } 16 17 public void eat(){ 18 System.out.println("Dog eat"); 19 } 20 }
public class Application { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.setName("kk"); System.out.println(dog1.getName()); //父类引用指向子类对象 Pet dog2 = new Dog(); Object dog3 = new Dog(); dog1.run(); // 执行子类的run(); dog2.run();//执行父类的run(); 但是因为子类重写了父类的run(); 所以还是执行了子类的run(); dog1.eat(); // dog2.eat(); //父类不能调用子类特有的方法,除非进行类型转换 ((Dog) dog2).eat(); } }
3、类与对象的关系
- 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是不能代表某一个具体的事物。
- 对象是抽象概念的具体实例
4、创建与初始化对象
- 使用new关键字创建对象
- 使用new关键字创建的时候,除了分配内存空间外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
- 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的,并且构造器有2个特点:(1)必须和类名相同;(2)必须没有返回类型,也不能写void
1 public class Student { 2 //一个类即使什么都不写,它也会存在一个方法 3 int id; 4 String name; 5 6 //无参构造 7 8 public Student() { 9 System.out.println("1"); 10 } 11 //有参构造 12 public Student(int id, String name) { 13 this.id = id; 14 this.name = name; 15 System.out.println("2"); 16 } 17 }
1 public class Application { 2 3 public static void main(String[] args) { 4 //使用new关键字,本质是在调用构造器 5 Student student = new Student(); 6 System.out.println("========================="); 7 Student a = new Student(1, "a"); 8 9 } 10 }
一旦定义有参构造,无参构造必须显示定义,否则无参构造会失效
5、super和this关键字
- super调用父类的构造方法,必须在构造方法的第一个;
- super必须只能出现在子类的方法或构造方法中;
- super和this不能同时调用构造方法(this也是只能在构造方法中的第一个);
this:本身调用者的对象,没有继承也能使用。this();本类的构造
super:代表父类对象的应用,只能在继承条件下使用。super();父类的构造
1 public class Person { 2 protected String name = "kk"; 3 4 public Person() { 5 System.out.println("Person Constructor!"); 6 } 7 8 public void print(){ 9 System.out.println("Person"); 10 } 11 }
1 public class Student extends Person{ 2 private String name = "cc"; 3 4 public Student() { 5 //隐藏代码,调用父类的无参构造 6 //super(); 7 System.out.println("Student Constructor!"); 8 } 9 10 public void test(String name){ 11 System.out.println(name); 12 System.out.println(this.name); 13 System.out.println(super.name); 14 } 15 public void print(){ 16 System.out.println("Student"); 17 } 18 public void test1(){ 19 print(); 20 this.print(); 21 super.print(); 22 } 23 }
1 public class Application { 2 3 public static void main(String[] args) { 4 Student student = new Student(); 5 System.out.println("===================="); 6 student.test("qq"); 7 System.out.println("====================="); 8 student.test1(); 9 } 10 }
6、方法的重写
需要有继承关系,子类重写父类的方法。
- 方法名必须相同;
- 参数列表必须相同;
- 修饰符范围可以扩大但不能缩小;
- 抛出的异常范围可以被缩小但不能扩大;
7、多态存在的条件
- 有继承关系
- 子类重写父类方法,static和final,private修饰的方法不能被重写。
- 父类引用指向子类
多态是方法的多态,属性没有多态性。
对象能执行哪些方法,主要看对象左边的类型,和右边关系不大。
Person p = new Student();
[引用类型] [实际对象]
8、instanceof 类型转换
instanceof 是二目运算符,用来测试一个对象是否为一个类的实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
类型转换:
- 父类引用执向子类对象
- 把子类转换为父类,向上转型;
- 把父类转换为子类,向下转型,需要强制转换;
1 public static void main(String[] args) { 2 Pet pet = new Dog(); 3 System.out.println(pet instanceof Dog); //true 4 System.out.println(pet instanceof Pet); //true 5 System.out.println(pet instanceof Object); //true 6 // System.out.println(obj instanceof String); // 编译报错 7 }
1 public static void main(String[] args) { 2 Dog dog = new Dog(); 3 dog.eat(); 4 Pet pet = dog; 5 ((Dog)pet).eat(); 6 }
9、抽象类
用abstract关键字来修饰的类,抽象类;用abstract来修饰方法,抽象方法。抽象类中可以没有抽象方法,但有抽象方法的类一定要声明为抽象类。抽象类中可以写普通方法。
抽象类不能使用new关键字来创建对象,它是用来让子类继承的。
抽象方法只有方法的声明,没有方法的实现,它是用来让子类实现的。
子类继承抽象类,那么必须实现抽象类没有实现的抽象的方法,否则该子类也要声明为抽象类。
1 public abstract class A { 2 public void add(){ 3 4 } 5 //抽象方法 6 public abstract void modify(); 7 }
1 public class B extends A{ 2 @Override 3 public void modify() { 4 5 } 6 }
10、接口
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有
- 接口:只有规范,方法都是public abstract,属性都是public static final修饰
接口都需要实现类,接口用interface来定义,实现类中使用implements来实现多个接口。接口中没有构造方法,不能被实例化。
1 public interface A { 2 3 void modify(); 4 5 void select(); 6 7 }
1 public interface C { 2 void delete(); 3 String getName(); 4 }
1 //可实现多个接口,但必须重写所有的方法 2 public class B implements A,C{ 3 4 @Override 5 public void modify() { 6 7 } 8 9 @Override 10 public void select() { 11 12 } 13 14 @Override 15 public void delete() { 16 17 } 18 19 @Override 20 public String getName() { 21 return null; 22 } 23 }
11、内部类
在一个类的内部再定义一个类。一个Java类中只能有一个public class,但可以有多个class。
- 成员内部类:通过外部类来实例化内部类,可以获得外部类的私有属性。
- 静态内部类
- 局部内部类
- 匿名内部类
1 public class Outer { 2 private int id = 10; 3 4 public void out(){ 5 System.out.println("outer method"); 6 } 7 //成员内部类 8 class Inner{ 9 public void in(){ 10 System.out.println("inner method"); 11 } 12 public void getOutId(){ 13 System.out.println(id); 14 } 15 } 16 17 }
1 public class Application { 2 3 public static void main(String[] args) { 4 Outer outer = new Outer(); 5 Outer.Inner inner = outer.new Inner(); //通过外部类来实例化内部类 6 inner.in(); 7 inner.getOutId(); 8 } 9 }
1 public class Outer { 2 private int id = 10; 3 4 public void out(){ 5 System.out.println("outer method"); 6 } 7 //静态内部类 8 public static class Inner{ 9 public void in(){ 10 System.out.println("static inner method"); 11 } 12 // public void getOutId(){ 13 // System.out.println(id); //无法访问非静态属性 14 // } 15 }
1 public class Outer { 2 public void method(){ 3 //局部内部类 4 class inner{ 5 public void in(){} 6 } 7 } 8 }
1 public class Application { 2 3 public static void main(String[] args) { 4 //匿名内部类 5 new Ap().test(); //匿名对象使用,不用将实例保存到变量中 6 new Service(){ 7 8 @Override 9 public void add() { 10 11 } 12 }; 13 } 14 } 15 class Ap{ 16 public void test(){ 17 System.out.println("a"); 18 } 19 } 20 interface Service{ 21 void add(); 22 }