文章目录
- 重载和重写的区别★★★
- Java的三大特性
- 请说明一下Super关键字的作用?
- static关键字的作用?
- final关键字的作用?
- super关键字和this关键字的作用?
- 面向对象的三大特性★★★
- 成员变量和局部变量的区别?
- Java能实现多继承么
- 抽象类(abstract class) 与接口(interface)的区别?★★★
- 能详细解释一下封装么?
- 继承你了解哪些?
- 多态你了解哪些?
重载和重写的区别★★★
重载(Overloading)和重写(Overriding)都是Java中面向对象编程的特性,它们都可以让子类继承父类的方法。但是它们之间有一些重要的区别:
-
定义方式:
- 重载(Overloading):在同一个类中,可以有多个方法名相同但参数列表不同的方法。当调用一个方法时,编译器会根据参数的数量、类型和顺序来判断调用哪个方法。
- 重写(Overriding):在子类中,必须定义与父类同名、参数类型和返回值类型相同的方法。这样才能覆盖掉父类中的方法,使得子类对象调用该方法时执行的是子类自己的代码。
-
访问权限:
- 重载(Overloading):方法名相同但参数列表不同,因此它们的访问权限是一样的,都是public、protected或private。
- 重写(Overriding):子类中的方法必须使用super关键字来调用父类的方法,这意味着子类中的方法具有比父类中相同的方法更低的访问权限。
总之,重载和重写都是Java中多态性的重要特性,但它们的作用和实现方式有所不同。重载允许在同一类中定义多个同名但参数不同的方法,而重写允许子类覆盖父类的方法并提供自己的实现。
Java的三大特性
Java的三大特性是:
- 面向对象编程(Object-Oriented Programming,OOP):Java是一种纯面向对象的编程语言,它支持封装、继承和多态等面向对象的特性。通过封装,Java可以将数据和方法封装在一起,形成一个类,从而实现对数据的保护;通过继承,Java可以从已有的类中继承属性和方法,避免重复编写代码;通过多态,Java可以让不同的对象对同一个消息做出不同的响应,提高了代码的复用性和灵活性。
- 平台无关性(Platform Independence):Java程序可以在不同的操作系统上运行,这是因为Java编译器将Java源代码编译成字节码(bytecode),然后由Java虚拟机(JVM)将字节码解释执行。因此,无论在哪个平台上安装了Java虚拟机,都可以运行Java程序。这种平台无关性使得Java成为一种非常适合开发跨平台应用程序的语言。
- 安全性(Security):Java提供了多种安全机制来保护应用程序的安全,包括沙箱安全模型、类加载器、安全管理器等。这些机制可以限制应用程序的访问权限,防止恶意代码的执行,保证了应用程序的安全性和稳定性。同时,Java还提供了加密和数字签名等标准安全协议,使得Java应用程序可以方便地与其他系统进行安全通信。
请说明一下Super关键字的作用?
在Java类中使用super来调用父类中的指定操作
-
super可以用来访问父类中定义的属性
-
super可以用于调用父类中定义的成员方法
-
super可以同于子类构造器中调用父类的构造器
static关键字的作用?
在Java中,static关键字有以下几种作用:
1.修饰类成员变量和方法:
- 修饰类成员变量:被static修饰的成员变量是静态变量,它们属于类而不是对象。静态变量可以在类的任何地方访问,且只有一份实例。例如:
- public static int count = 0;。
- 修饰类成员方法:被static修饰的方法是静态方法,它们不依赖于对象而是直接通过类名调用。静态方法可以在类的任何地方调用,且没有this指针。例如:public static void printCount() { System.out.println(count); }。
2.修饰局部变量:
- 被static修饰的局部变量成为静态局部变量,它们属于类而不是对象。静态局部变量只能在类的静态方法中初始化一次。例如:public static void test() { static int count = 0; count++; System.out.println(“count=” + count); }。
3.表示类和接口的常量:
-
被static修饰的常量是类和接口的常量,它们在整个程序中都是可见的。例如:public static final int MAX_COUNT = 100;。
- 表示线程安全:
-
被static修饰的方法可以保证多线程访问时的安全性。例如:public static synchronized void printCount() { System.out.println(count); }。
总之,static关键字可以用来修饰类、方法、局部变量、常量和线程安全等方面,具有不同的作用和意义。
final关键字的作用?
在Java中,final关键字有以下几种作用:
-
修饰类和方法:
- 修饰类:被final修饰的
类不能被继承
。例如:final class MyClass。 - 修饰方法:被final修饰的方法不能被子类
重写
。例如:final void myMethod() {}。
- 修饰类:被final修饰的
-
修饰变量:
- 修饰全局变量:被final修饰的全局变量只能在声明时赋值一次。例如:final int MAX_VALUE = 100;。
- 修饰局部变量:被final修饰的局部变量只能在定义时初始化一次。例如:final int x = 5;。
-
表示常量:
- final修饰的常量是不可修改的,一旦赋值就不能再改变。例如:final int MAX_VALUE = 100;。
-
表示线程安全:
- final修饰的实例方法可以保证多线程访问时的安全性。例如:final class MyClass { … }。
总之,final关键字可以用来修饰类、方法、变量和线程安全等方面,具有不同的作用和意义。
super关键字和this关键字的作用?
面向对象的三大特性★★★
面向对象编程的三大特性是封装、继承和多态。
- 封装(Encapsulation):封装是指将数据和方法捆绑在一起,形成一个类,对外部隐藏实现细节,只提供必要的接口给外部使用。通过封装,可以保护数据的安全性和完整性,防止外部程序直接访问和修改数据,从而提高程序的可维护性和稳定性。
- 继承(Inheritance):继承是指子类可以从父类中继承属性和方法,避免重复编写代码。通过继承,可以提高代码的复用性和灵活性,使得程序更加模块化和可扩展。但是需要注意的是,过度的继承会导致代码变得复杂和难以维护。
- 多态(Polymorphism):多态是指同一个方法可以根据不同的参数类型和数量表现出不同的行为。通过多态,可以提高代码的灵活性和可扩展性,使得程序更加通用和易于维护。Java中的多态主要有两种形式:方法重载(Method Overloading)和方法重写(Method Overriding)。
成员变量和局部变量的区别?
Java能实现多继承么
Java不支持多继承,它只支持单继承。这意味着一个类只能继承自一个直接父类,而不能同时继承多个父类。
在Java中,一个类可以实现多个接口。
抽象类(abstract class) 与接口(interface)的区别?★★★
抽象类和接口都是用来定义类或类的成员的,但它们之间有以下区别:
1. 实现方式不同:抽象类必须被子类实现,而接口可以被多个类实现。
2. 抽象方法和默认方法不同:抽象类中可以定义抽象方法和非抽象方法,而接口只能定义抽象方法。
3. 构造函数不同:抽象类可以定义构造函数,而接口不能定义构造函数。
4. final修饰符的使用不同:抽象类中可以定义final修饰符,而接口中的所有方法都不能被final修饰。
5. 继承限制不同:子类只能继承一个抽象类,而一个类可以实现多个接口。
总之,抽象类更像是一种“半成品”,它提供了一些基本的实现,但还需要子类去完善;而接口则更像是一种规范,它规定了一组方法和常量,但并不提供具体的实现。
能详细解释一下封装么?
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问 成员变量private,提供对应的getXxx()/setXxx()方法
- 封装可以被认为是一个保**护屏障,**防止该类的代码和数据被外部类定义的代码随机访问。
- 要访问该类的代码和数据,必须通过严格的接口控制。
- 封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
- 适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
程序涉及追求——>高内聚,低耦合
高内聚:类的内部数组操作细节自己完成,不允许外部干涉。
低耦合:仅对外暴露少量的方法用于使用。
关于四种权限修饰符的说明:
继承你了解哪些?
Java中继承是一种面向对象编程的基本概念,它允许一个类(子类)从另一个类(父类)中继承属性和方法。以下是Java中继承的一些基本知识:
1. 继承的语法:在Java中,使用extends关键字来声明一个类继承另一个类。例如:
class Animal {
// 父类中的属性和方法
}
class Dog extends Animal {
// 子类中的额外属性和方法
}
2. 子类可以重写父类的方法:子类可以覆盖(override)父类中定义的方法,以实现自己的行为。例如:
class Animal {
public void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("Dog is eating");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); //输出 "Dog is eating"
}
}
3. 子类可以访问父类中的公有、受保护和默认(package-private)成员:子类可以访问其继承的父类中的公有、受保护和默认(package-private)成员。例如:
class Animal {
public int age;
}
class Dog extends Animal {
public void bark() {
System.out.println("Woof! My age is " + age);
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.age = 3; //可以修改子类的属性age,但不能修改父类的属性age
dog.bark(); //输出 "Woof! My age is 3"
}
}
多态你了解哪些?
多态是同一个行为具有多个不同表现形式或形态的能力。
多态一般分为两种:重写式多态和重载式多态。
重载式多态,也叫编译时多态。也就是说这种多态再编译时已经确定好了。重载大家都知道,方法名相同而参数列表不同的一组方法就是重载。在调用这种重载的方法时,通过传入不同的参数最后得到不同的结果。
但是这里是有歧义的,有的人觉得不应该把重载也算作多态。因为很多人对多态的理解是:程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,这种情况叫做多态。 这个定义中描述的就是我们的第二种多态—重写式多态。
重写式多态,也叫运行时多态。这种多态通过动态绑定(dynamic binding)技术来实现,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。也就是说,只有程序运行起来,你才知道调用的是哪个子类的方法。 这种多态通过函数的重写以及向上转型来实现,我们上面代码中的例子就是一个完整的重写式多态。我们接下来讲的所有多态都是重写式多态,因为它才是面向对象编程中真正的多态。
总而言之我的理解:重载式多态,在编码等过程中,并没有很好的体现出多态的优势,但是不得否认也是多态的一种编写方式,而给出的重写式多态案例中,相比于重载式多态,在编码思路和代码量以及聚合度方面都较好的体现出了多态的优势。
多态的优点
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
/**
* 上面两行可以发现,show方法要求传入的是动物对象,因为猫和狗都继承了动物类,因此符合规范,
* 同时体现出多态的优势:一个形参可以对应多个实参,同时这也是一个重写式多态
*/
Animal a = new Cat(); // 向上转型:通过子类实例化父类
a.eat(); // 调用的是 Cat 的 eat
//a.work();如果运行这一行就会发现,无法调用work方法,因为动物类只有eat一个方法,从而cat失去了特有方法
Cat c = (Cat)a; // 向下转型:通过父类强制转化为子类
c.work(); // 调用的是 Cat 的 work
/**
* 上面两行体现了向下转型的用处,我们可以知道,对象a目前是一个动物对象,不能执行猫或者狗的特有方法
* 但是,如果通过向下转型,将动物a对象,转化为一个猫c对象,这样就可以调用猫的特有方法了
*/
/**
* 得出结论:
* 向上转型 : 通过子类对象(小范围)实例化父类对象(大范围),这种属于自动转换
* 向下转型 : 通过父类对象(大范围)实例化子类对象(小范围),这种属于强制转换
*/
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
//定义一个抽象类
abstract class Animal {
abstract void eat();
}
//下面的每一个类继承抽象类,重写接口中的方法
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}