面向对象总结
- 方法名称有多个单词,则第一个单词首字母小写,其他首字母大写
- 实参和形参,可变参数:用数组的方式来传递可变个数的参数
public void printInfo(String[] args) {
for(int i=0; i<args.length; i++) {
System.out.println(args[i]);
}
}
获取长度直接.length()即可,例如:"dnqoedno".length()
上例必须传入参数,即使为空数组,不能传入Null(不同于空数组)
下例可以传入Null
public void printInfo1(String... args) {
for(int i=0; i<args.length; i++) {
System.out.println(args[i]);
}
}
- 如果一个方法有多个的形参,可变的形参(...这种的参数)一定要放在所有的参数最后
- 栈:基础数据类型(具体值)和对象的引用(地址)
- 堆:所有的对象(包括自己定义的对象和字符串对象)
- 方法区:所有的class和static变量
- 一个类写了有参构造后,一定要有无参构造(虽然不会报错)
- 若构造器被封装了,即构造器私有化,是为了实现单例模式
- 什么是JavaBean:一个可复用的类,
(1)类是公共的
(2)有一个无参的公共的构造器
(3)有属性,属性一般是私有的,且有对应的get、set方法 - 重载和重写的区别,重写方法抛出的异常不能大于父类该方法的异常,重载是方法名相同
- 类对象,子类对象的实例化,基本数据类型创建,字符串创建过程内存怎么加载的
- Object类:public String toString(){} 用于把所有的类型都转为字符串进行输出,用于打印输出
- = 与equals()的区别是什么
- 包装类
//字符串转为其他类型
int i = Integer.parseInt("123");
float f = Float.parseFloat("0.123");
boolean b = Boolean.parseBoolean("false");
//其他类型转化成字符串类型:
String istr=(String)i; // 错误
String istr=String.valueOf(i);
String fstr=String.valueOf(f);
String bstr=String.valueOf(true);
- 接口与接口之间是继承要用extends,类与接口之间是实现,用implements
- 什么是默认方法?是为了实现修改接口而不影响子类
- 接口中不能有public void test(){.....},只能用default默认方法代替前者
- 接口中存在什么?
- 非静态abstract方法,无方法体 调用: 子类 . 方法名
- 非静态default方法 , 有方法体 调用: 父类/子类 . 方法名
- 静态方法,不能被子类修改的default 调用: 父类 . 方法名
- 不允许有public void test()
- 不允许有静态属性,属性一定为常量,是被那三个修饰的 调用:属性名,前面无"."
- 私有方法,只是为了解决接口代码重复问题 不可调用
- 私有静态方法:解决静态方法之间......的问题
- 私有非静态方法:解决非静态方法.....的问题
- 不允许有静态代码块
- 不允许有构造方法
- 例子:
public interface Sender {
public void Send();
}
public class MailSender implements Sender {
@Override
public void Send() {
System.out.println("this is mailsender!");
}
}
public class SmsSender implements Sender {
@Override
public void Send() {
System.out.println("this is sms sender!");
}
}
- 建工厂类:方法返回的是Sender类型,所以方法必须要用Sender修饰
public class SendFactory {
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
- 测试下:注意接收的对象要用接口Sender修饰
public class FactoryTest {
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produce("sms");
sender.Send();
}
}
// 输出:this is sms sender!
- 成员内部类,局部内部类,怎么调用内部类方法属性?
public class Test4 {
public int n = 0;
public void test() {
System.out.println("Test4");
}
class A{
public int n =10;
public void test() {
System.out.println("A");
}
}
public void test1() {
int n = 11;
System.out.println("test1");
class B{
int n = 100;
public void test() {
System.out.println("test1_B");
}
}
System.out.println("test1_B_n : " + new B().n);
System.out.println("test1_n : " + n);
}
}
- new Test4().new A().test();
public class Test5 {
public static void main(String[] args) {
System.out.println(new Test4().n);
new Test4().test();
System.out.println("===================");
System.out.println(new Test4().new A().n);
new Test4().new A().test();
System.out.println("===================");
new Test4().test1();
}
}
- 匿名内部类: 匿名内部类和匿名对象不是一回事
- 先定义一个接口 Interface()
- 有名字的匿名内部类:
- 尾部有分号
- 并没有创建新类
- 可以多次使用obj . method();
Interface obj = new Interface(){
@Override
public void method(){
.........
}
};
obj.method();
- 没名字的匿名内部类
new Interface(){
@Overrride
public void method(){
........
}
}.method();
- 末尾直接 . method();
- 只能使用一次
int num = new Scanner(System.in).nextInt;
int num = new Random().nextInt(2) + 2;
- 对象数组
错误: Person1[] p = new Peron1[3]();
错误: p[0] = Person1(11,"????");
Person1[] p = new Person1[3];
p[0] = new Person1(11,"????");
使用多态的好处
举例:
- 有一父类Employee员工类, n个子类讲师类,助教类,教授类等
- Employee有抽象方法work(),每个子类都重写work()
- 创建每个对象:
Employee one = new Teacher();
Employee two = new Assiatant();
Employee three = new Professor();
- 带来了统一性,每个对象都相当于一个类实例化来的,而且还有其特有的work方法
- 无论"="右边new的时候换成哪个子类对象,等号左边调用方法,属性都不会变化
- 每个对象都统一起来了,他们除了work之外都有相通的属性方法,比如身高,体重,专业等
上下转型
- 向上转型:其实就是多态写法,向上转型一定是安全的,
父类名称 对象名 = new 子类名称();
- 向下转型:还原向上转型
子类名称 对象名 = (子类名称)父类对象;
Animal animal = new Dog();
if (animal instanceof Dog){ // 看清大小写
Dog dog = (Dog) animal;
}
- 前提:
向上转型,只有向上转型后才可以使用向下转型
向下转型使用的子类名必须是向上转型的子类名
- 切记:下述代码错误
Animal animal = new Animal();
Dog dog = (Dog) animal; // 报错,只有向上转型后才可以用向下转型
Animal animal = new Cat();
Dog dog = (Dog) animal; // 报错
- 为什么要向下转型:当使用多态(向上转型)后,需要调用子类特有的方法
- 转型需要配合 instanceof 使用:
- 向上向下转型有什么意义?
当传入的参数不知道是什么类时,可以用最底层父类修饰:
public static void giveMeAPet(Animal animal){
if (animal instanceof Dog){
Dog dog = (Dog) animal;
dog.watchHouse;
}
if (animal instanceof Cat){
Cat cat = (Cat) animal;
cat.catchMouse;
}
}